PHP面向对象基本概念
class People{ public $name = 'nobody'; public function cry(){ echo '呱呱坠地'; } } $man = new Prople(); echo $man->name; echo $man->cry();
属性与方法的注意点
对于属性值,可以在声明属性的同时进行赋值,也可以先声明并不进行赋值,如果不复制,属性的默认值为null;
PHP的属性值必须是一个“直接的值”,不能是表达式(如:1+2)的值,或者函数的返回值等等
PHP中的函数不能重复定义(即函数名不能重复),但是全局函数名可以和类中的方法名一样
class Clock{ public function time(){ echo '现在时间戳是11111111'; } public function time2(){ echo '现在时间戳是',time(); } public function time3(){ echo '现在时间戳是',$this->time(); } } $c = new Clock(); $c->time(); //现在时间戳是11111111 $c->time2(); //调用系统函数,输出真实的时间戳 $c->time3(); //现在时间戳是11111111
构造函数详解
在类中,有一个构造函数,就是用来初始化对象用的,利用构造函数,就有机会操作对象,并改变它的值
工作原理:生成对象时,先按类的声明,把属性凑齐,再用__construct()去影响,再返回该对象
class Human{ public function __construct($name,$gender){ $this -> name = $name; $this -> gender = $gender; } public $name = null; public $gender = null; } $a = new Human('张飞','男'); $b = new Human('李四','男'); $c = new Human('黛玉','女'); echo $a -> name,"<br />"; //张飞 echo $b -> name,"<br />"; //李四 echo $c -> name,"<br />"; //黛玉
构造函数的作用时机:每当new一个对象,就会自动对new出来的新对象发挥作用
new ClassName()传的参数,是给构造函数用的
new ClassName()也可以不传参,但前提是与构造函数里的参数保持一致
一个类中,只允许存在一个构造函数
析构函数
构造函数是在对象产生的时候,自动执行
析构函数是在对象销毁的时候,自动执行
class Human{ public function __construct(){ echo "出生喽!"; } public $name = null; public $gender = null; public function __destruct(){ echo "还是跪了!"; } } $a = new Human(); $b = new Human(); $c = new Human(); $d = new Human(); //4生4死 unset($a); // 出生喽! 还是跪了! $b = false; // 出生喽! 还是跪了! $c = null; // 出生喽! 还是跪了!
对象的销毁:
显式销毁:unset(),赋值为null,都可以。
PHP是脚本语言,在代码执行到最后一行时,所有申请的内存都要释放,自然,对象的内存也要释放,所以对象也被销毁了
析构函数与回收机制详解
在上例中,如果将对象$b进行如下赋值操作$b = true,还是会立即触发析构函数,原理如下:
改变了$b的指向,原来内存中的Object对象就没有人指向它,所以会被回收
class Human{ public $name = null; public $gender = null; public function __destruct(){ echo "死了!"; } } $a = $b = $c = new Human(); unset($a); echo 'unset a<br />'; unset($b); echo 'unset b<br />'; unset($c); echo 'unset c<br />'; /* unset a unset b 死了 unset c */
原理如下:
this绑定
class Human{ public $name = 'lisi'; public function who(){ echo $this -> name; } public function test(){ echo $name; } } $a = new Human(); echo $a -> name,'<br />'; //lisi $a -> who(); //lisi
当一个对象调用其方法时,该方法执行之前,先完成一个绑定
$this绑到调动此方法的对象【睡调用就绑定谁】
在PHP中,方法想访问成员变量必须要使用this进行绑定,而在Java和C++等其他语言中,可以省略,默认访问成员变量,如test()方法在PHP中不合法,但在Java和C++中却可以
封装的概念
class Human{ public $money = 1000; } $lisi = new Human(); echo $lis -> money; //1000 //对属性进行封装 class Human{ private $money = 1000; public fuction shoeMoney(){ return $this -> money * 0.8; } } $lisi = new Human(); echo $lis -> shoeMoney();
私有的money的属性只能通过相应的方法进行访问,这就是封装在属性上的体现。在方法上的体现也是一个道理。
权限修饰符
用来说明:属性/方法的权限特点,写在属性/方法的前面,PHP共有3个权限修饰符
private:私有的,其定义的属性和方法只能在类内部进行访问
protect:保护的
public:公共的,其定义的属性和方法在任意位置都可以访问
class Human{ public $name = 'lisi'; private $money = 1000; public function shoeMoney(){ echo $this -> money; } } $a = new Human(); echo $a -> name,'<br />'; //lisi echo $a -> money; //私有属性,在类的外部不可读写 $a -> shoeMoney(); //1000
权限控制的BUG
class Human{ private $money = 1000; public function getMoney($people){ return $people -> money; } public function setMoney($people){ echo $people -> money -= 500; } } $zhangsan = new Human(); $lisi = new Human(); echo $lisi -> getMoney($zhangsan); $lisi -> setMoney($zhangsan); print_r($zhangsan);
从生活的角度看,李四读取和改变张三的钱,是不合理的
这是因为在PHP中,并不是以对象为单位俩控制权限,而是以类为单位进行权限控制封装MySQL类
继承的概念
class Human{ public $height = 160; public function cry(){ echo '呜呜呜呜'; } } class Stu extends Human{} $xiaoming = new Stu(); $xiaomming -> cry(); //呜呜呜呜
以一个类为父类,另一个类作为其子类,子类在继承父类的属性和方法的基础上,可以进一步的增添和修改
一个子类只能有一个父类
继承注意事项
私有属性可以理解为不能被继承(其实可以被继承,但无法操作)
public和protected都可以继承,并拥有访问和修改的权限
继承时,权限只能越来越宽松或者保持不变,不能越来越严格
构造方法的继承