2018-3-7 抽象类和抽象方法
抽象类和抽象方法:
抽象类:
在正常定义类的前面,加上关键字:abstract,那就构成抽象类。
abstract class 类名{.....类的定义.....}
抽象类就是用来做父类的,不能实例化对象,就是用来被继承的。
<?php abstract class A{ } $o1=new A(); //此处是错误的,不能为抽象类A实例化对象 var_dump($o1); ?>
抽象方法:
抽象方法是一个没有方法体(也没有大括号)的方法定义“头”而已。
形式:abstract function f1($x1,$y,$m); //注意后面有分号
抽象方法的作用:
同抽象类一样,配合抽象类,实现对下级类的“行为规范”。下级类完成该功能,但自己本身不做。
abstract class guai{ //guai类是抽象类 public $blood=100; protected $distance=30; protected abstract function attack(){ //attack是抽象方法 } } class snakeGuai extends guai{ //snakeGuai继承自抽象类guai function attack(){ //必须实现该抽象方法 echo "<br />吐火攻击"; $this->blood; } } $o1= new snakeGuai(); var_dump($o1); echo"<br>"; $o1->attack(); echo"<br>该蛇怪剩余的血为:".$o1->blood;
抽象类抽象方法细节关系描述:
1,一个方法定义为抽象方法,其所在的类必须定义为抽象类。
2,一个抽象类中,可以没有抽象方法。
3,子类继承自一个抽象类,则子类必须实现父类中的所有抽象方法,除非子类也继续作为抽象类
4,子类实现抽象父类的方法时,访问控制修饰符的范围不能降低,且方法的参数也须一致——其实这就是重写,所以要满足重写的要求。
通常面向对象语言的重载技术:
在一个类中,有多个同名的方法,每个方法的参数不同而已。这种现象就称为“重载”。
参数不同可以是:数量个数不同,或类型不同,或顺序不同。
例:
class A{ int function f1(int x){......} int function f1(int x, int y){.....} int function f1(string s int m){....} }
php中的重载:
属性重载:如果使用一个不存在的属性,就会去自动调用类中预先定义好的某个方法以处理数据;
方法重载:如果使用一个不存在的方法,就会去自动调用类中预先定义好的某个方法以处理该行为
属性重载:
取值:$v1 = 对象->属性; ===>自动调用类中的__get()方法
赋值:对象->属性 = XX值; ===>自动调用类中的__set()方法
判断是否存在:isset(对象->属性;) ===>自动调用类中的__isset()方法
销毁:unset(对象->属性;) ===>自动调用类中的__unset()方法
前提都是:类中要预先定义好这些方法。
class A{ public $p1=1; /*function __get($){ }*/ } $o1=new A(); echo "<b>o1的p1属性值为:".$o1->p1; echo "<b>o1的p2属性值为:".$o1->p2; //没有定义属性$p2,因此会报错
方法重载:
当使用一个对象调用一个不存在的普通方法的时候,会自动去调用预先定义好的"__call"方法。其中,该方法必须带2个参数,
/*重载*/ function f1(){ echo"<br>f1函数被执行(任务完成)"; } function f2($x,$y){ echo"<br>f1函数被执行(任务完成)"; return $x+$y; } class A{ public $p1=1; //当使用一个对象调用一个不存在的方法时,就会自动调用本方法 //其中$name就是本来要调用的方法名 //$array就是本来调用该方法时使用的实参数据,都装入该数组 function __call($name,$array){ $count=count($array); if($count==0){ f1(); }else if($count==2){ return f2($array[0],$array[1]); } } } $o1=new A(); $o1->f1(); //不存在的方法,不带实参 $v1=$o1-f1(1,2); //不存在的方法,并带两个实参 echo "<br>o1里面的p1=".$o1->p1; echo"<br>结果v1=".$v1;
当使用一个对象(类)调用一个不存在的静态方法的时候,会自动去调用预先定义好的"__callStatic"方法。其中,该方法必须带2个参数。其实跟前面一样!
上面所学的几个方法都被称为“魔术方法”:
__get(), __set(), __isset(), __unset(), __call(), __callstatic();
接口:interface
类:有属性,有方法;有类常量。
抽象类:有属性,有方法;有类常量; 还可以有抽象方法(只有方法头)
“更”抽象类(就是接口) :有接口常量;还可以有抽象方法(只有方法头)
可见,接口中,只有两类最简单特性信息:
接口常量: 其实就是常量。
抽象方法: 只有方法头——下级自然就应该去“实现”它。
一个类只能继承一个父类,但可以实现多个“上级接口”,语法形式:
class 类A extends 类B implements 接口1,接口2,.... { 。。。类定义语句。。。}
一个接口同样可以继承另一个接口(也是单继承):
interface 接口1 extends 接口2 {接口定义}