重写override
即子类中定义了与父类重名的成员,子类可以重写父类任意成员,通常重写使用来写父类的方法,用于扩展或者更改某些业务逻辑
重写父类成员之后,子类只会直接访问子类成员(覆盖)
不管时共有属性还是受保护属性,一旦重写,父类的就会不存在,但私有属性不会被覆盖而丢失
重写的要求:子类重写父类的方法,控制权不能该与父类,即子类可以比父类更开放
PHP7中要求被重写的方法必须与父类保持参数参数一致(数量和类型)
parent不能访问父类的属性,但可以访问静态属性,静态方法,常量和普通方法
<?php
class Human{
public $name ='human';
public function getMoney(){
echo 'hello world';
}
}
class Man extends Human{
public $name = 'man';
public function getMoney(){
echo '你好,世界';
}
}
$m = new Man();
echo $m->name;
echo $m->getMoney();
?>
PHP继承的特点
php只能单继承,即一个子类只有一个父类(有些语言支持多继承)
php中继承的只有私有方法不能被继承
php允许子类继承父类的构造方法和折构方法
静态延迟绑定
self时一种静态绑定,换言之就是当类进行编译的时候,self已经明确定义了类名,因此不论多少继承,也不管是子类还是父类自己来进行访问,self代表的都是当前类,如果想要选择性的来支持来访者,就需要使用静态延迟绑定
静态延迟绑定,即在类的内部用来代表本身的关机子部分不是在类编译时固定好的,而是当前方法被访问时动态的原则来访者所属的类。静态延迟绑定就是立吞static关键字代替静态绑定self,静态延迟绑定需要使用静态成员的重写
1.静态延迟绑定使用static关键字代替self进行类成员的访问
<?php
//父类
class Human{
//静态属性
public static $name = 'Human';
//静态方法
public static function getName(){
echo self::$name.',self访问'.'<br>';
echo static::$name.',sattic访问';
}
}
// $s = new Human();
// // $s::getName();
//子类继承
class Man extends Human{
//重写父类静态属性
public static $name = "man";
}
Man::getName(); //静态属性/方法要用::来访问
?>
最终类final
语法:final class 类名
final关键字不止修饰类表示类不可被继承,还能修饰方法,表示方法不能被重写
<?php
//类man可以被继承
class Man{
}
//类boy可以被继承
class boy extends man{
}
//定义类,不能被继承
final class girl{
}
//尝试继承girl
// class ligirl extends girl{}
// 报错Fatal error: Class ligirl may not inherit from final class (girl) in E:\phpstudy_pro\WWW\php.com\19.php on line 17
//final 修饰方法
class Human {
//可以重写
public function work(){
echo '工作'.'<br>';
}
//不允许重写
public final function eat(){
echo '很能吃'.'<br>';
}
}
class woman extends Human{
public function work(){
echo '努力工作';
}
}
$w = new woman();
$w->work();
$w->eat();
?>
抽象类abstract
抽象类,使用abstract关键字修饰的类,该类只能被继承,不能被实例化
语法:abstract class 类名
abstract还可以用来修饰方法(抽象方法),abstract修饰的方法不能有方法体{},而且抽象方法的类必须声明为抽象类
抽象方法的抽象被继承时要么自身是抽象类,要么实现所有抽象方法
<?php
//定义一个类
abstract class Human{}
//实例化
// $s =new Human(); 报错abstract修饰的类不能被实例化,只能被继承
//子类继承
class Man extends Human{}
//抽象方法类
abstract class Animal{
//抽象方法,没有方法体,用abstract关键字修饰
abstract public function eat();
}
//继承1
abstract class dog extends Animal{} // 子类继承有抽象方法的类的时候可以声明为抽象类
//继承2
class cat extends Animal{
//实现父类的抽象方法
public function eat(){}
}
?>
接口interface
接口,使用interface关键字定义,与类类似,专门用来规范一些公共性必须实现的方法
定义:interface 接口名{}
接口不是类不能被实例化
接口实现:接口是用来规范必须完成的事情,所以接口只能被类实现:implements
语法:class 类名 implements 接口名{}
接口成员:接口中只能定义共有抽象方法和接口常量,且接口常量不允许修改
实现接口的时候,必须实现接口中所以的抽象方法(或者用抽象类实现)
<?php
//定义接口
interface Human{
//接口体/接口成员
const NAME= '人';
public function eat(); //在接口中方法默认就自带关键字abstract
//其他内容不能有,只有常量和方法
}
//实现接口
class Man implements Human{
//实现接口方法
public function eat(){}
}
echo Man::NAME;
//可以用抽象类实现接口
abstract class Woman implements Human{
}
//接口继承,接口继承接口
interface Animal{}
//接口继承
interface dog extends Animal{}
//接口可以多继承,继承两个
interface Ape extends Human,Animal{}
?>