PHP继承
静态延迟绑定
定义:静态延迟绑定,即在类内部用来代表类本身的关键字部分不是在类编译时固定好,而是当方法被访问时动态的选择来访者所属的类.静态延迟绑定就是利用static关键字代替静态绑定self,静态延迟绑定需要使用到静态成员的重写.
1. 静态延迟绑定:使用static关键字代替self进行静态类成员访问
2. 静态延迟绑定一定是通过继承后的子类来进行访问才有效果
静态延迟绑定总结
最终类FINAL
定义:最终类,使用final关键字修饰类名,表示此类不可被继承
1. 基本语法: final class 类名
2. 最终类无法被继承
3. final关键字不止可以修饰类表示不可被继承,还能修饰方法,表示不能被子类重写
final关键字总结
抽象类Abstract
定义:抽象类,使用abstract关键字修饰的类.表示该类只能被继承,不能被实例化
1.基本语法:使用abstract关键字修饰类
//抽象类
abstract class Human{}
2. 抽象类无法实例化
//抽象类
abstract class Human{}
//$h = new Human();//错误:抽象类不能被实例化
3. 抽象类只能被继承
//抽象类
abstract class Human{}
class Man extends Human{}//正确:子类继承抽象父类
4. abstract关键字还可以修饰抽象方法.抽象方法不能有方法体.且有抽象方法的类必须声明为抽象类
5. 抽象方法因为要被子类继承实现,所以不能使用private修饰(私有方法不被继承).
6. 子类继承抽象类后,如果抽象类中有抽象方法,那么子类必须成为抽象类或者自己实现继承父类来的抽象方法(所有抽象方法)
抽象总结
接口interface
定义:接口interface,与类相似,专门用来规范一些共性类必须实现的方法
1. 接口定义:使用interface关键字,后跟接口名字(与类结构一样
interface Human{} //定义接口
2.接口不是类,不可以被实例化:
//错误:接口不能被实例化
//new Human();
3.implements实现接口:接口是类的规范,因此接口只能被类来实现
//只能类来实现接口
class Man implements Human{}
4. 接口成员:接口中只能定义public抽象方法(无须带abstract关键字)和接口常量
接口中允许的方法只能是public抽象的,无须带abstract关键字,带了反而出错!
即:接口中除了接口常量,不能有任何其他具体实现,无论是属性还是方法.因此除了接口常量,它只能拥有抽象方法.
简单助记:(抽象)接口对应抽象方法(除接口常量)
5. 接口必须被具体类实现方法或抽象类"抽象实现"(即不具体实现)
6.实现接口的类成员,不允许重写接口中的常量,不允许增加接口方法的控制权限
7. 接口可以继承extends接口,而且接口允许多继承接口(可以曲线实现类的多继承)
晕,感觉这个多继承例子是演示兽人吗?
接口总结
trait代码复用
定义:trait是为类似php的单继承语言而准备的一种代码复用机制.trait可以使得单继承语言摆脱为了复用而不得不继承的尴尬,让面向对象变得更加纯粹.
1. trait是一种类似class的关键字
trait eat{}
2. trait内部拥有一个类能够拥有的成员属性(包含静态),成员方法(包含静态),但不能有常量.
3.trait是用来代码复用的,不能实例化也不能被继承(不是类)
4. trait是用来将公共代码提供给其他类使用的,而类要使用trait的前提是加载对应的trait
5. 一个类可以使用多个treat
6. 如果同时引入的trait中有同名方法,那么会发生冲突:解决冲突的方法是(A)用insteadof代替处理以及(B)对被替代方法使用别名.
7. 同名覆盖:如果类中有和trait同名的成员==>>属性不允许重名;类的方法覆盖trait的方法.
8. 继承覆盖:子类的父类和子类使用的trait有同名方法,则子类使用的trait的覆盖父类同名方法;如果子类要访问父类同名方法,可以在trait同名方法中使用parent访问父类同名方法.
同名方法覆盖优先级:类自己同名方法 > trait同名方法 > 父类同名方法
子类要访问父类同名方法,在trait同名方法eat()中加入parent::eat();即可访问子类的父类同名方法:
trait Eat{
public function eat(){
parent::eat();
}
}
一般trait较少会预料到和父类有同名方法这种情形,一旦遇到就是这种解决方法.
9. trait不允许自己访问,只是用来给其他类代码复用.因此允许类在使用trait时更高里面方法的访问控制权: 在as之后,使用目标访问修饰符
注意:此时trait中的别名public eshow()方法存在,本尊private show()方法仍然存在!只是访问权限不同.
10. trait中可以使用抽象方法,用来规范使用类必须实现对应抽象方法:使用类要么为抽象类,要么必须实现抽象方法
trait总结:
PHP重载
注意:php重载和其他编程语言的重载不是完全等价.
1. 魔术方法:系统预先设计好的,只需要开发者实现的方法.魔术方法以双下划线__开头.对象在符合某些特定情况下会自动调用.构造方法,析构方法,克隆方法就是魔术方法.
2. php重载是指某些容错处理(为了特定情况系统自动调用),在访问没有权限或者不存在的属性或方法的时候,会自动触发的魔术方法.
- 属性重载
- 方法重载
3. 属性重载:当php对象访问不存在的或者没有权限访问的属性的时候会自动触发
- __get($key):读属性的时候触发
- __set($key, $value):写属性的时候触发
- __isset($key):外部调用isset()函数或者empty()函数时自动触发
- __unset($key):外部调用unset()结构删除对象属性时触发
- __tostring():对象被当做普通变量输出或者连接时自动调用.
<?php
echo 'php属性重载<br>';
//定义演示类.用到属性重载所有魔术方法
class Human{
private $age = 10;
//属性重载魔术方法演示
//读取方法
public function __get($name){
echo $name, '---', __METHOD__, '<br>';
}
//设置方法
public function __set($name,$value){
echo $name, ':', $value, '---', __METHOD__, '<br>';
}
//判定方法
public function __isset($name){
echo $name, '---', __METHOD__, '<br>';
}
//删除方法
public function __unset($name){
echo $name, '---', __METHOD__, '<br>';
}
//tostring方法普通输出
public function __toString(){
echo '---', __METHOD__, '<br>';
return 'toString';
}
}
//实例化
$h = new Human();
//访问属性
//触发我们写的__get魔术方法(事件)
//跳过原本php错误机制且中止运行:禁止外部访问private属性
echo $h->age;
//根据private属性外部禁止操作:实际上$age并没有被外部访问
//设置
//触发我们写的__set魔术方法
//同样跳过php原有错误机制中止程序:禁止外部设置private属性
$h->age=100;
//根据private属性外部禁止操作:实际上$age并没有被外部更改
//判定
//触发我们写的__isset魔术方法并跳过原有错误机制中止程序:禁止外部访问private属性
isset($h->age);
//删除
//触发我们写的__unset魔术方法并跳过原有错误机制中止:禁止外部访问private属性
unset($h->age);
//根据private属性外部禁止操作:实际上age并没有被删除
//普通输出
//触发我们写的__toString魔术方法并跳过原有错误机制中止:不能输出对象
echo $h;
//输出var_dump($h)观察会发现:
//自写的魔术方法会因具体情况由系统自动触发,会跳过php原有错误机制:显示错误信息并中止
//但并不能改变php原有机制:外部禁止访问/更改private属性
var_dump($h);
由上可知:在类外部还是不能访问/修改private属性.但是我们可以在魔术方法(类内部:可以访问所有权限成员)中增添代码突破这一限制,如下.
4. 属性重载的目的:一方面为了不让程序运行出错中止,另一方面可以在类内部由我们自己控制内容的访问
5. 方法重载:访问不存在或禁止访问方法时触发(亦或是某种特殊情况例如构造方法)
- public __call ( string
$name
, array$arguments
) : mixed -- 对象调用一个不可访问方法时,__call() 会被调用。 - public static __callStatic ( string
$name
, array$arguments
) : mixed -- 类访问不可调用静态方法时,__callStatic() 会被调用。
$name 参数是要调用的方法名称。$arguments 参数是一个枚举数组,包含着要传递给方法 $name 的参数。
6, 方法重载的目的:抑制错误信息,控制自定义访问权限
注:上文有小错误,__callStaic格式应为:public static __callStatic ( string $name
, array $arguments
)
php重载总结:(php'重载'≠别的编程语言'重载')
对象遍历
定义:遍历对象,其实就是将对象中所有公有属性以键值对的形式取出并进行访问.