面向对象php学习笔记19:PHP继承[静态延迟绑定,final类和方法,抽象类和抽象方法,接口,trait,php重载overload,对象遍历]

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'重载'≠别的编程语言'重载')

对象遍历

定义:遍历对象,其实就是将对象中所有公有属性以键值对的形式取出并进行访问.

1. 使用foreach对对象进行遍历(类外部只显示public属性)

 对象遍历总结:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值