抽象类是一种特殊的类,而接口是一种特殊的抽象类。他们通常配合面向对象的多态性一起使用
一、抽象类
1、抽象方法就是没有方法体的方法,是为了方便继承而引入的。不能使用private修饰为私有的
2、只要在声明类时有一个方法是抽象方法,那么这个类就是抽象类,抽象类也要使用abstract关键字修饰。抽象类中可以有不是抽象的成员方法。
3、由于抽象类中有没有被实现的抽象方法,所以抽象类是不能被实例化的,即创建不了对象,也就不能直接使用它。那使用抽象类有什么作用呢?
使用抽象类就包含了继承关系,它是为它的子类定义公共接口,将它的操作交给子类去实现。就是将抽象类作为子类重载的模板使用,定义抽象类就相当于定义了一种规范,这种规范要求子类去遵守。当子类继承抽象类之后,就必须把抽象类中的抽象方法按照子类自己的需要去实现。子类必须把父类中的抽象方法全部实现,否则子类中还存在抽象方法,所以还是抽象类,不能实例化对象
<?php
abstract class AbstractClass
{
// 强制要求子类定义这些方法
abstract protected function getValue();
abstract protected function prefixValue($prefix);
// 普通方法(非抽象方法)
public function printOut() {
print $this->getValue() . "\n";
}
}
class ConcreteClass1 extends AbstractClass
{
protected function getValue() {
return "ConcreteClass1";
}
public function prefixValue($prefix) {
return "{$prefix}ConcreteClass1";
}
}
$class1 = new ConcreteClass1;
$class1->printOut();
echo $class1->prefixValue('FOO_') ."\n";
/*
ConcreteClass1
FOO_ConcreteClass1
*/
4、子类定义了一个可选参数,而父类抽象方法的声明里没有,则两者的声明并无冲突。
abstract 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";