PHP OOP - 抽象类
PHP - 什么是抽象类和抽象方法?
抽象类和抽象方法是当父类有一个命名的方法,但需要其子类来完成具体任务时使用的。
抽象类是一个至少包含一个抽象方法的类。抽象方法是声明了但在代码中未实现的方法。
抽象类或抽象方法使用 abstract
关键字来定义:
语法
<?php abstract class ParentClass { abstract public function someMethod1(); abstract public function someMethod2($name, $color); abstract public function someMethod3() : string; } ?>
当从抽象类继承时,子类方法必须使用相同的名称,以及相同或更宽松的访问修饰符。因此,如果抽象方法被定义为 protected
,子类方法必须定义为 protected
或 public
,但不能是 private
。此外,必需参数的类型和数量必须相同。但是,子类可以拥有额外的可选参数。
因此,当子类从抽象类继承时,我们遵循以下规则:
- 子类方法必须使用相同的名称并重新声明父类的抽象方法
- 子类方法必须使用相同或更宽松的访问修饰符
- 必需参数的数量必须相同。但是,子类可以拥有额外的可选参数
让我们看一个例子:
实例
<?php // 父类 abstract class Car { public $name; public function __construct($name) { $this->name = $name; } abstract public function intro() : string; } // 子类 class Audi extends Car { public function intro() : string { return "选择德国品质!我是$this->name!"; } } class Volvo extends Car { public function intro() : string { return "为身为瑞典人而自豪!我是$this->name!"; } } class Citroen extends Car { public function intro() : string { return "法国奢华!我是$this->name!"; } } // 从子类创建对象 $audi = new audi("Audi"); echo $audi->intro(); echo "<br>"; $volvo = new volvo("Volvo"); echo $volvo->intro(); echo "<br>"; $citroen = new citroen("Citroen"); echo $citroen->intro(); ?>
例子解释
Audi、Volvo 和 Citroen 类继承自 Car
类。这意味着 Audi、Volvo 和 Citroen 类可以使用 Car
类的公共 $name
属性和公共 __construct()
方法,这是由于继承机制。
但是,intro()
是一个抽象方法,应该在所有子类中定义,并返回一个字符串。
PHP - 更多抽象类实例
让我们看另一个例子,其中抽象方法有一个参数:
实例
<?php abstract class ParentClass { // 带参数的抽象方法 abstract protected function prefixName($name); } class ChildClass extends ParentClass { public function prefixName($name) { if ($name == "Bill Gates") { $prefix = "Mr."; } elseif ($name == "Jane Gates") { $prefix = "Mrs."; } else { $prefix = ""; } return "{$prefix} {$name}"; } } $class = new ChildClass; echo $class->prefixName("Bill Gates"); echo "<br>"; echo $class->prefixName("Jane Gates"); ?>
让我们看另一个例子,其中抽象方法有一个参数,而子类有两个未在父类的抽象方法中定义的可选参数:
实例
<?php abstract class ParentClass { // 带参数的抽象方法 abstract protected function prefixName($name); } class ChildClass extends ParentClass { // 子类可以定义父类的抽象方法中不存在的可选参数 public function prefixName($name, $separator = ".", $greet = "Dear") { if ($name == "Bill Gates") { $prefix = "Mr"; } elseif ($name == "Jane Gates") { $prefix = "Mrs"; } else { $prefix = ""; } return "{$greet} {$prefix}{$separator} {$name}"; } } $class = new ChildClass; echo $class->prefixName("Bill Gates"); echo "<br>"; echo $class->prefixName("Jane Gates"); ?>