PHP – 继承



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

PHP 提供了在其对象模型中实现继承的所有功能。在 PHP 软件开发中使用继承可以实现代码重用,消除冗余的代码重复,并进行逻辑组织。

假设您需要设计一个新类,其大部分功能已经在现有类中定义好了。继承允许您扩展现有类,添加或删除其功能,并开发一个新类。事实上,PHP 具有“extends”关键字来建立现有类和新类之间的继承关系。

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

当一个新类(以下称为继承类、子类、子类等)与现有类(称为基类、超类、父类等)存在“IS A”关系时,就会出现继承。

PHP Inheritence

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

示例

请看下面的示例:

<?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();
?>

它将产生以下输出

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

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

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

示例

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

<?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();
?>

浏览器输出如下所示:

Title: PHP Fundamentals Price: 450
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 "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();
?>

它将产生以下输出

This is parent constructor
This is child class destructor

但是,如果子类没有构造函数,则它可以像普通类方法一样从父类继承(如果它没有声明为私有)。

示例

请看下面的示例:

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

它将产生以下输出

This is parent constructor

PHP 不允许通过扩展多个父类来开发类。您可以进行层次继承,其中类 B 扩展类 A,类 C 扩展类 B,依此类推。但是 PHP 不支持多重继承,其中类 C 试图同时扩展类 A 和类 B。但是,我们可以扩展一个类并实现一个或多个接口。我们将在后续章节中学习有关接口的知识。

广告