继承是面向对象编程方法的基本原则之一。继承是一种软件建模方法,它支持扩展现有类的功能以构建新类,而不是从头开始构建。
PHP 提供在其对象模型中实现继承的所有功能。在 PHP 软件开发中加入继承可实现代码重用、消除冗余代码重复和逻辑组织。
假设你需要设计一个新类,其大部分功能已在现有类中明确定义。继承允许您扩展现有类、添加或删除其功能以及开发新类。事实上,PHP 有 “extends” 关键字来建立现有类和新类之间的继承关系。
class newclass extends oldclass {
...
...
}
当一个新类(以下称为继承类、子类、子类等)与现有类(将称为基类、超类、父类等)具有“IS A”关系时,继承就出现了。
在 PHP 中,当通过扩展另一个类来定义一个新类时,子类会从父类继承 public 和 protected 方法、属性和常量。您可以自由地覆盖继承方法的功能,否则它将保留父类中定义的功能。
例子
请看下面的例子 -
<?php
class myclass {
public function hello() {
echo "你好,来自父类信息" . PHP_EOL;
}
public function thanks() {
echo "谢谢,来自父类信息" . PHP_EOL;
}
}
class newclass extends myclass {
public function thanks() {
echo "谢谢,来自子类信息" . PHP_EOL;
}
}
# 父类对象
$obj1 = new myclass;
$obj1->hello();
$obj1->thanks();
# 子类对象
$obj2 = new newclass;
$obj2->hello();
$obj2->thanks();
?>
它将产生以下输出 -
谢谢,来自父类信息
你好,来自父类信息
谢谢,来自子类信息
如前所述,子类继承父类的 public 和 protected 成员(属性和方法),子类可以引入其他属性或方法。
在下面示例中,我们使用 Book 类作为父类。在这里,我们创建了一个扩展 Book 类的 ebook 类。
新类有一个额外的属性 – 格式 (指示电子书的文件格式 – EPUB、PDF、MOBI 等)。ebook 类定义了两个新方法来初始化和输出 ebbok 数据 – 分别是 getebook() 和 dispebook()。
例子
下面给出了完整的继承代码示例——
<?php
class Book {
/* 成员变量 */
protected int $price;
protected string $title;
public function getbook(string $param1, int $param2) {
$this->title = $param1;
$this->price = $param2;
}
public function dispbook() {
echo "Title: $this->title Price: $this->price \n";
}
}
class ebook extends Book {
private string $format;
public function getebook(string $param1, int $param2, string $param3) {
$this->title = $param1;
$this->price = $param2;
$this->format = $param3;
}
public function dispebook() {
echo "Title: $this->title Price: $this->price\n";
echo "Format: $this->format \n";
}
}
$eb = new ebook;
$eb->getebook("PHP 基本知识", 450, "EPUB");
$eb->dispebook();
?>
浏览器输出如下所示 -
Format: EPUB
如果你仔细看一下 getebook() 函数,前两个赋值语句实际上是 getbook() 函数,ebook 类继承了这个函数。因此,我们可以使用 parent 关键字和范围解析运算符来调用它。
使用以下命令更改 getebook() 函数代码 -
public function getebook(string $param1, int $param2, string $param3) {
parent::getbook($param1, $param2);
$this->format = $param3;
}
类似地,dispebook() 函数中的第一个 echo 语句被替换为对父类中 dispbook() 函数的调用 -
public function dispebook() {
parent::dispbook();
echo "Format: $this->format<br/>";
}
继承的构造函数
父类构造函数中的构造函数由子类继承,但如果子类定义了构造函数,则不能在子类中直接调用它。
为了运行父构造函数,需要在子构造函数中调用 parent::__construct()。
例子
请看下面的例子 -
<?php
class myclass{
public function __construct(){
echo "这是父构造函数". PHP_EOL;
}
}
class newclass extends myclass {
public function __construct(){
parent::__construct();
echo "这是子类析构函数" . PHP_EOL;
}
}
$obj = new newclass();
?>
它将产生以下输出 -
这是子类析构函数
但是,如果子类没有构造函数,那么它可以像普通的类方法一样从父类继承(如果它没有声明为 private)。
例子
请看下面的例子 -
<?php
class myclass{
public function __construct(){
echo "这是父构造函数". PHP_EOL;
}
}
class newclass extends myclass{ }
$obj = new newclass();
?>
将产生以下输出 -
PHP 不允许通过扩展多个父级来开发类。您可以进行 分层继承,其中类 B 扩展类 A,类 C 扩展类 B,依此类推。
但是 PHP 不支持 多重继承,其中类 C 试图同时扩展类 A 和类 B。
但是,我们可以扩展一个类并实现一个或多个接口。我们将在后续章节中学习接口。