目录

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
// Parent class
abstract class Car {
  public $name;
  public function __construct($name) {
    $this->name = $name;
  }
  abstract public function intro() : string;
}

// Child classes
class Audi extends Car {
  public function intro() : string {
    return "Choose German quality! I'm an $this->name!";
  }
}

class Volvo extends Car {
  public function intro() : string {
    return "Proud to be Swedish! I'm a $this->name!";
  }
}

class Citroen extends Car {
  public function intro() : string {
    return "French extravagance! I'm a $this->name!";
  }
}

// Create objects from the child classes
$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 类可以使用 public $name 属性以及 Car 类中的 public __construct() 方法(因为继承)。

但是, intro() 是一个抽象方法,应该在所有子类中定义,并且它们应该返回一个字符串。



PHP - 更多抽象类示例

让我们看另一个例子,其中抽象方法有一个参数:

示例

<?php
abstract class ParentClass {
  // Abstract method with an argument
  abstract protected function prefixName($name);
}

class ChildClass extends ParentClass {
  public function prefixName($name) {
    if ($name == "John Doe") {
      $prefix = "Mr.";
    } elseif ($name == "Jane Doe") {
      $prefix = "Mrs.";
    } else {
      $prefix = "";
    }
    return "{$prefix} {$name}";
  }
}

$class = new ChildClass;
echo $class->prefixName("John Doe");
echo "<br>";
echo $class->prefixName("Jane Doe");
?>
亲自试一试 »

让我们看另一个例子,其中抽象方法有一个参数,并且子类有两个未在父类抽象方法中定义的可选参数:

示例

<?php
abstract class ParentClass {
  // Abstract method with an argument
  abstract protected function prefixName($name);
}

class ChildClass extends ParentClass {
  // The child class may define optional arguments that are not in the parent's abstract method
  public function prefixName($name, $separator = ".", $greet = "Dear") {
    if ($name == "John Doe") {
      $prefix = "Mr";
    } elseif ($name == "Jane Doe") {
      $prefix = "Mrs";
    } else {
      $prefix = "";
    }
    return "{$greet} {$prefix}{$separator} {$name}";
  }
}

$class = new ChildClass;
echo $class->prefixName("John Doe");
echo "<br>";
echo $class->prefixName("Jane Doe");
?>
亲自试一试 »