类的扩展
开发者使用 OOP 的主要原因之一是它能够重用现有的代码,同时,还可以添加或覆盖功能。在 PHP 中,关键字 extends 用来建立类之间的父/子关系。
如何做...
1.在子类中,使用关键字 extends 来设置继承。在下面的例子中,Customer 类扩展了 Base 类。 Customer 的任何实例都将继承可见的方法和属性,在本例中为 $id、getId() 和 setId() :
class Base
{
protected $id;
public function getId()
{
return $this->id;
}
public function setId($id)
{
$this->id = $id;
}
}
class Customer extends Base
{
protected $name;
public function getName()
{
return $this->name;
}
public function setName($name)
{
$this->name = $name;
}
}2.您可以强迫任何使用你的类的开发者通过标记为 abstract 的方法来定义一个方法。在这个例子中,Base 类将 validate() 方法定义为 abstract。之所以它必须是抽象的,是因为从父类 Base 类的角度无法准确地确定子类如何验证:
如果一个类包含一个抽象方法,那么这个类本身必须声明为抽象的。
3.PHP 仅支持单线继承。 下面的示例显示了一个类 Member,它继承了 Customer 。而 Customer 则继承自 Base:
4.为了满足类型提示,可以使用目标类的任何子类。在下面的代码片段中显示的 test() 函数,需要一个 Base 类的实例作为参数。继承线内的任何类都可以被接受为参数。传递给 test() 的其他任何东西都会抛出一个 TypeError :
如何运行...
在第一个要点中,定义了一个 Base 类和一个 Customer 类。为了便于演示,将这两个类的定义放在一个文件中,即 chap_04_oop_extends.php ,并添加以下代码:
请注意,$id 属性以及 getId() 和 setId() 方法都是从父类 Base 类继承到子类 Customer 中的:

为了说明抽象方法的使用,想象一下,你希望给任何扩展 Base 的类添加某种验证能力。问题是,我们无法知道在继承的类中可能会验证什么。唯一可以确定的是,你必须有一个验证能力。
把前面解释中提到的同一个 Base 类,添加一个新的方法 validate() 。将该方法标记为抽象方法,并且不要定义任何代码。注意当子类 Customer 类扩展 Base 时,会发生什么。

如果你再把 Base 类标记为抽象类,但没有在子类中定义一个 validate() 方法,就会产生同样的错误。最后,继续在子类 Customer 中实现 validate() 方法:
然后你可以添加以下代码来测试结果:
这是输出:

为了展示单线继承,在前面步骤1所示的 Base 和 Customer 的第一个例子中添加一个新的 Member 类:
创建一个 Member 的实例,注意,在下面的代码中,所有的属性和方法都可以从每个继承类中获得,即使不是直接继承的:
这是输出:

现在定义一个函数 test(),该函数将 Base 的实例作为参数:
请注意,Base、Customer和 Member的实例都可以作为参数。
这是输出:

但是,如果你试图用一个不在继承线中的对象实例运行 test() ,就会抛出 TypeError:
我们可以从下图中观察到这一点:

最后更新于