PHP面向对象(OOP)的继承和接口
OOP的继承是从一个基类得到一个或多个类的机制
继承自另一个类的类被称为该类的子类
子类将继承父类的特性,这些特性由属性和方法组成
子类可以增加父类之外的新功能,因此子类也被称为父类的“扩展”
在PHP中,类继承通过extends关键字实现
继承自其他类的类成为子类或派生类,子类所继承的类成为父类或基类
PHP只支持单继承,且PHP不支持方法重载
class Computer {function run(){echo'我是父类';}}
class NoteBookComputer extends Computer {}
$notebookcomputer = new NoteBookComputer();
echo $notebookcomputer ->run();
字段和方法的重写(覆盖)
有些时候,并不是特别需要父类的某些字段或方法,那么可以通过子类的重写来修改父类的字段和方法
class Computer {
public $_name ='Name';
protected function run() {echo'我是父类';}
}
class NoteBookComputer extends Computer {
public $_name ='newName';
public function run() {echo'我是子类';}
}
子类调用父类的字段或方法
为了安全,我们一般将父类的方法封装了起来,这样,外部就无法调用,只能被继承它的子类所看到
这个时候,就需要通过子类操作来调用父类了
class Computer {
protected function run() {echo'我是父类';}
//这里修饰符要用protected,private(私有的)在子类是无法调用的</strong>
}
class NoteBookComputer extends Computer {
public function getRun() {echo $this ->run();}
//用$this关键字
}
重写以后调用父类的方法
这个时候就必须使用语法:父类名::方法() 或 parent::方法()调用
class Computer {
protected function run() {return '我是父类方法';}
}
class NoteBookComputer extends Computer {
public function run() {echo parent::run();}
}
final 关键字可以防止类被继承或方法被重写
有些时候只想做个独立的类(称为终极类)
不想被其他类继承使用,那么就必须使用这个关键字。建议只要是单独的类,都加上这个关键字。
final class Computer { // 无法继承的类
final public function run() {}
// 用在字段或者方法前面表示该字段或方法可以被继承但是不能被重写,否则报错
}
抽象类和方法(abstract):
抽象方法很特殊,只在父类中声明(抽象类中的所有抽象方法都必须在子类中重写,否则报错),但在子类中实现
只有声明为 abstract 的类可以声明抽象方法
抽象类不能被实例化,只能被继承
抽象类是用来给子类继承的类,抽象方法必须被子类方法重写
抽象类里可以创建普通方法,普通方法可以被子类继承且不用必须重写
abstract class Computer {abstract function run();}
//run()后面直接接结束语(;),不需要加{}
//抽象方法不能实现方法体的内容
class NotebookComputer extends Computer {
public function run() {echo'我实现了';}
}
接口(interface):
接口定义了实现某种服务的一般规范,声明了所需的函数和常量,但不指定如何实现
之所以不给出实现的细节,是因为不同的实体可能需要用不同的方式来实现公共的方法定义
关键是要建立必须实现的一组一般原则,只要满足了这些原则才能说实现了这个接口
1.接口内的方法必须全部为抽象方法(不需要声明 abstract和方法体)
2.接口内的抽象方法必须是public
3.成员(字段)必须是常量
interface Computer {
const NAME ='Name';
public function run();
}
class NotebookComputer implements Computer {
//接口通过implements实现而不是通过extends继承
public function run() {echo'实现了接口的方法';}
}
$notebookcomputer = new NoteBookComputer();
$notebookcomputer ->run();
echo Computer::NAME;(NoteBookComputer::NAME;)
//类名::常量名(可以是接口名,也可以是子类类名),来获取常量的值
子类可以实现多个接口,类的继承不能继承多个类
interface Computer1 {public function run();}
interface Computer2 {public function book();}
class NotebookComputer implements Computer,Notebook {
//<strong>两个接口名用英文逗号隔开以实现多接口</strong>
public function run() {echo'实现了接口的方法';}
public function book() {echo'实现了接口的方法';}
}
接口可以继承其他接口
interface Computer3 extend Computer2{}