PHP面向对象
面向对象编程
面向对象编程也叫做OOP编程(Objected Oriented Programming),是一种编程思想,在很多现代编程语言中都有面向对象编程的概念
面向对象编程的思想就是把具有相似特性的事物抽象成类,通过对类的属性和方法的定义实现代码共用
将实现某一特定功能的代码部分进行封装,这样可被多处调用,而且封装的粒度越细小被重用的概率越大
OOP达到了软件工程的三个目标:重用性、灵活性和扩展性
面向对象的三大特性
封装性
把一个类(对象)的属性和方法封装起来,外部只有被授权的方法或操作才可以访问
继承性
指子类可以继承父类的属性和方法作为子类的属性和方法,并且子类也可以自定义属性和方法
多态性
指在父类中定义的属性或行为被子类继承之后. 可以具有不同的数据类型或表现出不同的行为。这使得同一个属性或行为在父类及其各个子类中具有不同的语义
面向对象内容
类
具有相同属性和行为的一组对象的集合
对象
描述客观事件的一个实体。可以通过对象调用类的属性与行为
类和对象的关系
类:汽车图纸
对象:生产出来的汽车
我们可以根据 汽车图纸 来 制造出 一辆真正的汽车
换成程序关系就是 类 实例化 出来 得到的产物就是对象
成员变量
定义在类内部的变量。该变量的值对外是不可见的,但是可以通过成员函数访问,在类被实例化为对象后,该变量即可称为对象的属性
成员函数
定义在类的内部,可用于访问对象的数据
父类
一个类被其他类继承,可将该类称为父类,或基类,或超类
子类
一个类继承其他类称为子类,也可称为派生类
重载
函数或者方法有同样的名称,但是参数列表不相同的情形,这样的同名不同参数的函数或者方法之间,互相称之为重载函数或者方法
抽象性
抽象性是指将具有一致的数据结构(属性)和行为(操作)的对象抽象成类。一个类就是这样一种抽象,它反映了与应用有关的重要性质,而忽略其他一些无关内容。任何类的划分都是主观的,但必须与具体的应用有关
构造函数
主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中
析构函数
析构函数(destructor) 与构造函数相反,当对象结束其生命周期时(例如对象所在的函数已调用完毕),系统自动执行析构函数。析构函数往往用来做"清理善后" 的工作
访问修饰符
PHP 对属性或方法的访问控制
public 公共修饰符
父类:内部和外部都能访问
继承的子类:内部和外部都能访问
protected 受保护修饰符
父类:内部能访问,外部不能访问
继承的子类:内部能访问,外部不能访问
private 私有修饰符
父类:内部能访问,外部不能访问
继承的子类:内部不能访问,外部不能访问
static
使用 static 关键字可以用来标识静态属性,也可以用来标识静态方法
声明类属性或方法为静态,就可以不实例化类直接访问
静态的成员属于类所有,所以我们在静态方法里,不能使用$this来引用静态成员
使用self关键字来调用
示例代码
<?php
// 命名空间
namespace User;
// 父类
class BaseController
{
// 成员变量
public $name = '父类';
protected $age = 18;
private $money = 100;
/**
* 构造函数
*/
public function __construct()
{
echo '父类的构造函数';
}
/**
* 获取父类的私有属性
*/
public function getMoney()
{
return $this->money;
}
/**
* 父类的方法
*/
public function age()
{
$this->age += 2;
}
}
// User是子类 使用extends关键字去继承父类
class User extends BaseController
{
// 定义成员变量
private $nickname;
public $email = 'admin@qq.com';
// 定义常量
const PI = 3.1415926;
// 定义静态变量
static $demo = 1;
/**
* 构造函数
*/
public function __construct($nickname)
{
// 手动继承父类的构造函数
parent::__construct();
echo "在实例化的时候自动调用";
$this->nickname = $nickname;
echo '子类的构造函数';
}
/**
* 获取昵称的值
*/
public function getNickname()
{
// 内部访问对象成员
echo $this->nickname;
return $this;
}
/**
* 设置昵称的值
*/
public function setNickname($nickname)
{
$this->nickname = $nickname;
}
/**
* 获取常量
*/
public function getConst(){
// 类内部访问常量
return self::PI;
}
/**
* 内部获取父类的私有属性
*/
public function getParentMoney()
{
return $this->money;
}
/**
* 内部获取父级的受保护属性
*/
public function getParentAge()
{
echo $this->age;
return $this;
}
/**
* 静态方法
*/
static public function sleep()
{
// 类内部访问静态属性
return self::$demo;
}
// 从父类继承过来的方法,子类有权去修改,这种方式就是多态
public function age()
{
$this->age += 5;
}
/**
* 析构函数
*/
public function __destruct()
{
echo "在对象调用完成后自动触发的方法";
//在销毁的时候 复原一些设置
$this->nickname = '';
}
}
// 实例化User类
$User = new User('demo');
// 外部访问对象成员
echo $User->email; // admin@qq.com
// 访问对象的私有成员
echo $User->nickname; // 报错
// 通过对象的函数访问对象的私有属性
$User->getNickname();
// 类外部访问常量
echo User::PI;// 3.1415926
// 外部访问静态属性
echo User::$demo; // 1
// 外部访问静态方法
echo User::sleep(); // 1
// 外部子类访问父类的私有成员
echo $User->money;// 报错
// 通过子类的函数访问父类私有属性
echo $User->getParentMoney();// 报错
// 通过父类提供函数访问自己私有属性
echo $User->getMoney();// 100
// 外部子类访问父类的受保护属性
echo $User->age;// 报错
$User->getParentAge();// 18
echo '<br />';
// 对象链调用
$User->getNickname()->getParentAge();
命名空间
PHP命名空间为了避免产生类名冲突而产生的
1、命名空间采用namespace来声明
2、命名空间语法必须在文件的第一行定义
3、命名空间会影响三种元素:类、函数、常量
4、不提倡在同一个文件中定义多个命名空间
5、use 别名使用
demo.php
//定义了一个名字空间
namespace demo;
function time()
{
return "demo空间里面的time函数";
}
const PHP_OS = 'demo空间里面的常量';
class Test
{
public function __construct()
{
echo 'demo空间里面的Test类';
}
}
index.php
header('Content-Type:text/html;charset=utf-8');
//引入刚刚定义的命名空间文件
include_once('demo.php');
// 内置函数
echo time();
// 命名空间里面的函数
echo demo\time();
echo \demo\time();
//内置常量
echo PHP_OS;
// 命名空间里面的常量
echo demo\PHP_OS;
// 命名空间里面的类
$obj = new demo\Test();
//使用别名
use demo as hello;
$obj2 = new hello\Test();