本页目录
PHP 有抽象类和抽象方法。任何一个类,如果它里面至少有一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的。
定义为抽象的类不能被实例化。
被定义为抽象的方法只是声明了其调用方式(参数),不能定义其具体的功能实现。
继承一个抽象类的时候,子类必须定义父类中的所有抽象方法;
并遵循常规的 继承
签名兼容性 规则。
另外,这些方法的访问控制必须和父类中一样(或者更为宽松)。
例如某个抽象方法被声明为受保护的,那么子类中实现的方法就应该声明为受保护的或者公有的,而不能定义为私有的。
abstract 关键字用于定义抽象方法与抽象类。
抽象方法
抽象方法指没有方法体的方法,具体就是在方法声明的时候没有 {} 括弧以及其中的内容,而是直接在声明时在方法名后加上分号结束。
(接口中的方法,必须全部是抽象方法,所以接口中的抽象方法不需要使用 abstract 关键字,直接用分号结束即可)
定义:一个方法如果没有方法体,则这个方法就是抽象方法
- 一个方法没有方法体,直接用分号结束的方法;
- 如果是抽象方法,必须使用 abstract 抽象关键字形容
**抽象方法的作用:**就是规定子类必须有这个方法,且将功能交给子类来处理,只写出来方法的结构,而没有实现(无方法体),具体的功能实现交给具体的子类根据自己的需求实现
abstract 关键字用于定义抽象方法,语法:
abstract function function_name();抽象类
- 只要有 abstract 修饰的类就是抽象类
- 除了在抽象类中可以有抽象方法之外,和正常的类完全一样
- 抽象类不能实例化对象
- 如果有抽象类,就必须有这个类的子类,
并且在子类中写方法覆盖抽象类中的抽象方法(加上方法体)
- 子类必须全部重写父类中的抽象方法,这个子类才能被实例化,如果只是实现部分,那么这个子类还是抽象类
抽象类不能产生实例对象,通常是将抽象方法做为子类方法重载的模板使用的,且要把继承的抽象类里的方法都实现。实际上抽象类是方便继承而引入的。
**抽象类的作用:**就是严格要求子类的结构,所以抽象类其实就是一个规范。
特点
-
顾名思义,它是抽象的,当然也就是不能被实例化的。所以,抽象类一般是作为我们的基类来进行定义的。
-
在一个类中,只要有一个方法被定义为抽象的,那么这个类就必须加上 abstract 关键字成为抽象类。
-
被定义为抽象的方法只声明其调用方式,不能定义其具体的功能实现。
-
子类必须定义父类中的所有抽象方法,这些方法的访问控制必须和父类一致或者更为宽松。
-
方法的调用方式必须匹配,即类型和所需参数数量必须一致。
子类实现的抽象方法可以增加参数但必须有默认值。
何时使用抽象
抽象类定义的是类的模板
实例
<?phpabstract class AbstractClass{ // 强制要求子类定义这些方法 abstract protected function getValue(); abstract protected function prefixValue($prefix);
// 普通方法(非抽象方法) public function printOut() { print $this->getValue() . PHP_EOL; }}
class ConcreteClass1 extends AbstractClass{ protected function getValue() { return "ConcreteClass1"; }
public function prefixValue($prefix) { return "{$prefix}ConcreteClass1"; }}
class ConcreteClass2 extends AbstractClass{ public function getValue() { return "ConcreteClass2"; }
public function prefixValue($prefix) { return "{$prefix}ConcreteClass2"; }}
$class1 = new ConcreteClass1;$class1->printOut();echo $class1->prefixValue('FOO_') . PHP_EOL;
$class2 = new ConcreteClass2;$class2->printOut();echo $class2->prefixValue('FOO_') . PHP_EOL;?>执行以上代码,输出结果为:
ConcreteClass1FOO_ConcreteClass1ConcreteClass2FOO_ConcreteClass2此外,子类方法可以包含父类抽象方法中不存在的可选参数。
例如,子类定义了一个可选参数,而父类抽象方法的声明里没有,则也是可以正常运行的。
<?phpabstract class AbstractClass{ // 我们的抽象方法仅需要定义需要的参数 abstract protected function prefixName($name);
}
class ConcreteClass extends AbstractClass{
// 我们的子类可以定义父类签名中不存在的可选参数 public function prefixName($name, $separator = ".") { if ($name == "Pacman") { $prefix = "Mr"; } elseif ($name == "Pacwoman") { $prefix = "Mrs"; } else { $prefix = ""; } return "{$prefix}{$separator} {$name}"; }}
$class = new ConcreteClass;echo $class->prefixName("Pacman"), "n";echo $class->prefixName("Pacwoman"), "n";?>输出结果为:
Mr. PacmanMrs. Pacwoman