Php 简明教程

PHP – Inheritance

继承是面向对象编程方法论的基本原则之一。继承是一种软件建模方法,它允许扩展现有类以构建新类,而不是从头开始构建新类。

PHP 提供了所有功能在其对象模型中实现继承。在 PHP 软件开发中纳入继承会产生代码再利用,消除冗余的代码重复及逻辑组织。

想象一下你需要设计一个新类,这个类的大部分功能已经在一个现有类中得到明确定义。继承允许你扩展现有类,添加或移除其功能,并开发一个新类。事实上,PHP 有“extends”关键词来建立现有类和新类之间的继承关系。

class newclass extends oldclass {
   ...
   ...
}

当一个新类(以后将被称为继承类、子类、子类,等等)与一个现有类(将被称为基类、超类、父类,等等)拥有“是”关系时,继承就会出现。

php inheritence

在 PHP 中,当通过扩展另一个类来定义一个新类时,子类会继承来自父类的公共和受保护的方法、属性和常量。你可以自由重写继承方法的功能,否则它将按照父类中定义的那样保留其功能。

Example

请看以下示例:

<?php
   class myclass {
      public function hello() {
         echo "Hello from the parent class" . PHP_EOL;
      }
      public  function thanks() {
         echo "Thank you from parent class" . PHP_EOL;
      }
   }
   class newclass extends myclass {
      public function thanks() {
         echo "Thank you from the child class" . PHP_EOL;
      }
   }

   # object of parent class
   $obj1 = new myclass;
   $obj1->hello();
   $obj1->thanks();

   # object of child class
   $obj2 = new newclass;
   $obj2->hello();
   $obj2->thanks();
?>

它将生成以下 output

Hello from the parent class
Thank you from parent class
Hello from the parent class
Thank you from the child class

如前所述,子类继承父类的公共和受保护成员(属性和方法)。子类可以引入其他属性或方法。

在下面的示例中,我们使用 Book class 作为父类。在这里,我们创建一个 ebook class 来扩展 Book 类。新类有一个其他属性 - format (表示电子书的文件格式 - EPUB,PDF,MOBI 等)。电子书类定义了两个新方法来初始化和输出电子书数据,分别是 getebook()dispebook()

Example

完整的继承示例代码如下所示:

<?php
   class Book {

      /* Member variables */
      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 Fundamentals", 450, "EPUB");
   $eb->dispebook();
?>

浏览器 output 如下所示:

Title: PHP Fundamentals Price: 450
Format: EPUB

如果你仔细查看 getebook() 函数,前两个赋值语句实际上是 getebook() 函数,而电子书类已经继承了它。因此,我们可以使用 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/>";
}

Constructor in Inheritance

父类构造函数中的构造函数由子类继承,但是如果子类定义了一个构造函数,则无法在子类中直接调用它。

为了运行一个父构造函数,需要在子构造函数内调用 parent::__construct()

Example

请看以下示例:

<?php
   class myclass{
      public function __construct(){
         echo "This is parent constructor". PHP_EOL;
      }
   }
   class newclass extends myclass {
      public function __construct(){
         parent::__construct();
         echo "This is child class destructor" . PHP_EOL;
      }
   }
   $obj = new newclass();
?>

它将生成以下 output

This is parent constructor
This is child class destructor

然而,如果子类没有构造函数,那么它可以从父类继承构造函数,就像一个普通的类方法(如果它不是声明为私有的)。

Example

请看以下示例:

<?php
   class myclass{
      public function __construct(){
         echo "This is parent constructor". PHP_EOL;
      }
   }
   class newclass extends myclass{ }
   $obj = new newclass();
?>

它将生成以下 output

This is parent constructor

PHP 不允许通过扩展多个父类来开发一个类。你可以有 hierarchical inheritance ,其中类 B 扩展类 A,类 C 扩展类 B,以此类推。但是 PHP 不支持 multiple inheritance ,其中类 C 试图同时扩展类 A 和类 B。然而,我们可以扩展一个类并实现一个或多个 interfaces 。我们将在后续章节之一中学习关于接口的内容。