PHP 保留字列表包括 “abstract” 关键字。当使用 “abstract” 关键字定义类时,它不能被实例化,即你不能声明此类的新对象。一个 抽象类(Abstract Class)可以由另一个类扩展。
abstract class myclass {
// class body
}
如上所述,您不能声明此类的对象。因此,以下语句 -
$obj = new myclass;
将导致如下所示的错误消息 -
PHP Fatal error: Uncaught Error: Cannot instantiate abstract class myclass
抽象类可以包括属性、常量或方法。类成员可以是 public、private 或 protected 类型。类中的一个或多个方法也可以定义为 abstract。
如果类中的任何方法是抽象的,则该类本身必须是抽象类。换句话说,普通类不能定义抽象方法。
这将引发错误 -
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
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)
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 "分数百分比: ". $s1->percent() . PHP_EOL;
?>
它将产生以下输出 -
分数百分比: 60
PHP 抽象类和接口的区别
PHP 抽象类的概念与接口非常相似。但是,接口和抽象类之间存在一些差异。
抽象类(Abstract class) | 接口(Interface) |
---|---|
使用 abstract 关键字定义抽象类 | 使用 interface 关键字定义接口 |
抽象类无法实例化 | 接口无法实例化。 |
抽象类可以有普通方法和抽象方法 | 接口必须仅使用参数和返回类型声明方法,而不能使用任何 body 声明方法。 |
抽象类由子类扩展,子类必须实现所有抽象方法 | 接口必须由另一个类实现,该类必须提供接口中所有方法的功能。 |
可以具有 public、private 或 protected 属性 | 不能在 interface 中声明属性 |