[关闭]
@Chiang 2020-01-08T14:24:48.000000Z 字数 1608 阅读 598

抽象类

PHP


  • PHP 5 支持抽象类和抽象方法。定义为抽象的类不能被实例化。任何一个类,如果它里面至少有一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的。被定义为抽象的方法只是声明了其调用方式(参数),不能定义其具体的功能实现。
  • 继承一个抽象类的时候,子类必须定义父类中的所有抽象方法;另外,这些方法的访问控制必须和父类中一样(或者更为宽松)。例如某个抽象方法被声明为受保护的,那么子类中实现的方法就应该声明为受保护的或者公有的,而不能定义为私有的。此外方法的调用方式必须匹配,即类型和所需参数数量必须一致。例如,子类定义了一个可选参数,而父类抽象方法的声明里没有,则两者的声明并无冲突。 这也适用于 PHP 5.4 起的构造函数。在 PHP 5.4 之前的构造函数声明可以不一样的。
  1. <?php
  2. abstract class AbstractClass
  3. {
  4. // 强制要求子类定义这些方法
  5. abstract protected function getValue();
  6. abstract protected function prefixValue($prefix);
  7. // 普通方法(非抽象方法)
  8. public function printOut() {
  9. print $this->getValue() . "\n";
  10. }
  11. }
  12. class ConcreteClass1 extends AbstractClass
  13. {
  14. protected function getValue() {
  15. return "ConcreteClass1";
  16. }
  17. public function prefixValue($prefix) {
  18. return "{$prefix}ConcreteClass1";
  19. }
  20. }
  21. class ConcreteClass2 extends AbstractClass
  22. {
  23. public function getValue() {
  24. return "ConcreteClass2";
  25. }
  26. public function prefixValue($prefix) {
  27. return "{$prefix}ConcreteClass2";
  28. }
  29. }
  30. $class1 = new ConcreteClass1;
  31. $class1->printOut();
  32. echo $class1->prefixValue('FOO_') ."\n";
  33. $class2 = new ConcreteClass2;
  34. $class2->printOut();
  35. echo $class2->prefixValue('FOO_') ."\n";
  36. ?>
  37. 以上例程会输出:
  38. ConcreteClass1
  39. FOO_ConcreteClass1
  40. ConcreteClass2
  41. FOO_ConcreteClass2
  1. <?php
  2. abstract class AbstractClass
  3. {
  4. // 我们的抽象方法仅需要定义需要的参数
  5. abstract protected function prefixName($name);
  6. }
  7. class ConcreteClass extends AbstractClass
  8. {
  9. // 我们的子类可以定义父类签名中不存在的可选参数
  10. public function prefixName($name, $separator = ".") {
  11. if ($name == "Pacman") {
  12. $prefix = "Mr";
  13. } elseif ($name == "Pacwoman") {
  14. $prefix = "Mrs";
  15. } else {
  16. $prefix = "";
  17. }
  18. return "{$prefix}{$separator} {$name}";
  19. }
  20. }
  21. $class = new ConcreteClass;
  22. echo $class->prefixName("Pacman"), "\n";
  23. echo $class->prefixName("Pacwoman"), "\n";
  24. ?>
  25. 以上例程会输出:
  26. Mr. Pacman
  27. Mrs. Pacwoman

老代码中如果没有自定义类或函数被命名为“abstract”,则应该能不加修改地正常运行。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注