抽象类的特性:
1、定义为抽象的类不能被实例化。
2、如果它里面至少有一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的。
3、被定义为抽象的方法只是声明了其调用方式(参数),不能定义其具体的功能实现。
4、继承一个抽象类的时候,子类必须定义父类中的所有抽象方法(这些方法的访问控制必须和父类中一样(或者更为宽松)。)
demo
abstract class AbstractClass
{
// 强制要求子类定义这些方法
abstract protected function getValue();
abstract protected function prefixValue($prefix);
// 普通方法(非抽象方法)
public function printOut() {
print $this->getValue() . "\n";
}
}
class ConcreteClass1 extends AbstractClass
{ //父类定义了俩个抽象方法,如子类只实现了其中一个,则报如下错误
//Fatal error: Class ConcreteClass1 contains 1 abstract //method and must therefore be declared abstract or //implement the remaining methods //(AbstractClass::prefixValue)
protected function getValue() {
return "ConcreteClass1";
}
// 且子类的访问权限不能低于父类,如果将如下子类的访问方式改为private则会报如下错误
//Fatal error: Access level to //ConcreteClass1::prefixValue() must be protected (as in //class AbstractClass) or weaker
public function prefixValue($prefix) {
return "{$prefix}ConcreteClass1";
}
}
//当实例化一个抽象类时,Fatal error: Cannot instantiate //abstract class AbstractClass
//$obj = new AbstractClass();
// 但是我们可以这么使用
##########################################################
abstract class Foo
{
static function bar()
{
echo "test\n";
}
}
Foo::bar();
##########################################################
$obj = new ConcreteClass1();
echo $obj->getValue();
5、子类可以定义一个可选参数(也就是必须要有默认值),而父类抽象方法的声明里没有,则两者的声明并无冲突。
abstract class AbstractClass
{
// 我们的抽象方法仅需要定义需要的参数
abstract protected function prefixName($name);
}
class ConcreteClass extends AbstractClass
{
// 我们的子类可以定义父类签名中不存在的可选参数
// 如果这里的$separator没有默认值,则会报Fatal error: 、、//Declaration of ConcreteClass::prefixName() must be //compatible with that of AbstractClass::prefixName()
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";
6、抽象类可以没有抽象方法,反过来有抽象方法的类一定要声明为抽象类
abstract class A{
public function show(){
echo 'A';
}
}
class B extends A{
public function hello(){
echo 'B';
parent::show();
}
}
$obj = new B;
$obj->hello(); // BA
7、抽象类定义的顺序
// 正确的定义顺序
abstract class horse extends animal {
public function get_breed() { return "Jersey"; }
}
class cart extends horse {
public function get_breed() { return "Wood"; }
}
// 错误的定义顺序,将会导致horse类找不到
class cart extends horse {
public function get_breed() { return "Wood"; }
}
abstract class horse extends animal {
public function get_breed() { return "Jersey"; }
}
8、抽象方法可以为静态方法
abstract class FOO
{
abstract static function dump();
}
class BAR extends FOO
{
static function dump(){var_dump("BAR");}
}
BAR::dump(); // string(3) "BAR"
9、一个抽象类继承另一个抽象类时,抽象方法不需要声明为抽象的
//Fatal error: Can't inherit abstract function //class1::someFunc() (previously declared abstract in //class2)
abstract class class1 {
abstract public function someFunc();
}
abstract class class2 extends class1 {
abstract public function someFunc();
}
//下面的是正确的
abstract class class1 {
abstract public function someFunc();
}
abstract class class2 extends class1 {
}