PHP – 抽象类



PHP 的保留字列表包括“abstract”关键字。当一个类用“abstract”关键字定义时,它不能被实例化,即你不能声明此类的新对象。抽象类可以被另一个类扩展。

abstract class myclass {
   // class body
}

如上所述,你**不能声明此类的对象**。因此,以下语句 -

$obj = new myclass;

将导致如下所示的**错误**消息 -

PHP Fatal error:  Uncaught Error: Cannot instantiate abstract class myclass

抽象类可能包含属性、常量或方法。类成员可以是公有、私有或受保护类型。类中的一种或多种方法也可以定义为抽象方法。

如果类中的任何方法是抽象的,那么该类本身必须是抽象类。换句话说,普通类不能在其内部定义抽象方法。

这将引发**错误** -

class myclass {
   abstract function myabsmethod($arg1, $arg2);
   function mymethod() #this is a normal method {
      echo "Hello";
   }
}

**错误消息**将显示为 -

PHP Fatal error:  Class myclass contains 1 abstract method 
and must therefore be declared abstract

你可以使用抽象类作为父类并用子类扩展它。但是,子类必须为父类中的每个抽象方法提供具体的实现,否则将遇到错误。

示例

在以下代码中,**myclass** 是一个**抽象类**,**myabsmethod()** 是一个**抽象方法**。它的派生类是**mynewclass**,但它没有在其父类中实现抽象方法。

<?php
   abstract class myclass {
      abstract function myabsmethod($arg1, $arg2);
      function mymethod() {
         echo "Hello";
      }
   }
   class newclass extends myclass {
      function newmethod() {
         echo "World";
      }
   }
   $m1 = new newclass;
   $m1->mymethod();
?>

在这种情况下,**错误消息**为 -

PHP Fatal error:  Class newclass contains 1 abstract method and must 
therefore be declared abstract or implement the remaining 
methods (myclass::myabsmethod) 

它表明 newclass 应该实现抽象方法,或者它应该被声明为抽象类。

示例

在以下 PHP 脚本中,我们有**marks** 作为抽象类,其中 percent() 是一个抽象方法。另一个**student** 类扩展了**marks** 类并实现了它的 percent() 方法。

<?php
   abstract class marks {
      protected int $m1, $m2, $m3;
      abstract public function percent(): float;
   }

   class student extends marks {
      public function __construct($x, $y, $z) {
         $this->m1 = $x;
         $this->m2 = $y;
         $this->m3 = $z;
      }
      public function percent(): float {
         return ($this->m1+$this->m2+$this->m3)*100/300;
      }
   }

   $s1 = new student(50, 60, 70);
   echo "Percentage of marks: ". $s1->percent() . PHP_EOL;
?>

它将产生以下**输出** -

Percentage of marks: 60

PHP 中接口和抽象类的区别

PHP 中抽象类的概念与接口非常相似。但是,接口和抽象类之间存在一些区别。

抽象类

接口

使用 abstract 关键字定义抽象类

使用 interface 关键字定义接口

抽象类不能被实例化

接口不能被实例化。

抽象类可以具有普通方法和抽象方法

接口必须仅声明带参数和返回类型的方法,而不能带任何主体。

抽象类被子类扩展,子类必须实现所有抽象方法

接口必须由另一个类实现,该类必须提供接口中所有方法的功能。

可以具有公有、私有或受保护的属性

接口中不能声明属性

广告