继承
使用关键字extends来继承一个类
class Child extends Parent {
}
class A{
var $name = '张三';
function demo(){
echo $this->name;
}
}
class B extends A{
var $name = '李四';
}
$b = new B();
$b->demo(); // 李四
继承之后可以对父类属性方法进行重写
class B extends A{
function demo(){
echo $this->name . '棒棒棒!';
}
}
$b = new B();
$b->demo(); // 张三棒棒棒!
如果继承时,不想二次覆盖重写父类的构造函数,可以类似使用Python的super方法:parent::__construct
// 一个父类
class A{
public $name;
function __construct($name){
$this->name = $name;
}
}
// 子类继承父类并利用父类方法
class B extends A{
public $age;
function __construct($name, $age)
{
parent::__construct($name); // 子类构造方法调用父类方法
$this->age = $age;
}
}
接口
接口通过interface关键字来定义的,接口中定义的所有方法都必须是公有,这是接口的特性
接口中无法定义构造函数,但是可以定义常量
实现类可以使用implements继承接口类,实现类中必须实现所有的接口类方法
interface iTemplate
{
public function setVariable($name, $var);
public function getHtml($template);
}
class Template implements iTemplate
{
private $vars = array();
public function setVariable($name, $var){
$this->vars[$name] = $var;
}
public function getHtml($template){
foreach($this->vars as $name => $value) {
$template = str_replace('{' . $name . '}', $value, $template);
}
return $template;
}
}
接口像是一种协议,所有继承接口类都将遵循接口的方法实现
抽象
使用abstract定义抽象类,定义为抽象的类不能被实例化
继承一个抽象类的时候,子类必须定义父类中的所有抽象方法,这些方法的访问控制必须和父类中一样,或者更为宽松
抽象类中的抽象方法不可以定义为私有,不然无法让子类继承,外部访问不到
abstract class AbstractClass
{
// 强制要求子类定义这些方法
abstract protected function getValue();
abstract protected function prefixValue($prefix);
// 普通方法(非抽象方法)
public function printOut() {
print $this->getValue() . PHP_EOL;
}
}
子类必须定义所有父类的抽象方法,但可以不定义其他普通方法
class ConcreteClass1 extends AbstractClass
{
protected function getValue() {
return "ConcreteClass1";
}
public function prefixValue($prefix) {
return "{$prefix}ConcreteClass1";
}
public function abc(){
echo "hahah";
}
}
此外,子类方法可以包含父类抽象方法中不存在的可选参数
一般继承抽象类和接口,要将extends语句写在implements前面
抽象类可以继承抽象类,且不能重写抽象父类的抽象方法
abstract class Human
{
abstract function eat();
}
abstract class Sutdent extends Human
{
abstract function study();
abstract function eat();
}
若重写抽象父类的抽象方法eat()会报错Fatal error: Can't inherit abstract function Human::eat() (previously declared abstract in Sutdent)
- 抽象类和接口类联系
- 都是用于声明某一种事物,规范名称、参数,形成模块
- 无详细的实现细节
- 都可以用继承,接口可以继承接口形成新的接口,抽象类可以继承抽象类从而形成新的抽象类
- 抽象类和接口类区别
- 抽象类可以有属性、普通方法、抽象方法,但接口不能有属性、普通方法、可以有常量
- 抽象类可以有构造函数,接口没有
- 一个类只继承一个抽象类,但可以继承多个接口
总结:抽象类声明是什么,接口类声明做什么