什么是PHP中的抽象类?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (11)

什么是php中的抽象类?它可以在哪里使用?

提问于
用户回答回答于

抽象类是一个至少包含一个抽象方法的类,该抽象方法是一种没有任何实际代码的方法,只是名称和参数,并且已被标记为“抽象”。

这样做的目的是提供一种模板来继承和强制继承类来实现抽象方法。

因此抽象类是普通类和纯粹接口之间的东西。接口也是抽象类的一个特例,其中所有方法都是抽象的。

请参阅PHP手册的这一部分以作进一步参考。

用户回答回答于

抽象类是包含一个或多个抽象方法的类。抽象方法是声明但不包含实现的方法。抽象类可能不被实例化,需要子类为抽象方法提供实现。

1.不能实例化抽象类:定义为抽象的类不能实例化,包含至少一个抽象方法的任何类也必须是抽象的。

例子如下:

abstract class AbstractClass
{

    abstract protected function getValue();
    abstract protected function prefixValue($prefix);


    public function printOut() {
        echo "Hello how are you?";
    }
}

$obj=new AbstractClass();
$obj->printOut();
//Fatal error: Cannot instantiate abstract class AbstractClass

2.包含至少一个抽象方法的任何类也必须是抽象的。抽象类可以有抽象方法和非抽象方法,但它必须至少包含一个抽象方法。如果一个类至少有一个抽象方法,那么必须声明该类为抽象。

注:特征支持使用抽象方法,以便对展览类提出要求。

例子如下:

class Non_Abstract_Class
{
   abstract protected function getValue();

    public function printOut() {
        echo "Hello how are you?";
    }
}

$obj=new Non_Abstract_Class();
$obj->printOut();
//Fatal error: Class Non_Abstract_Class contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Non_Abstract_Class::getValue)

3.抽象方法不能包含体。

定义为抽象的方法只需声明方法的签名,它们不能定义实现。但非抽象方法可以定义实现。

abstract class AbstractClass
{
   abstract protected function getValue(){
   return "Hello how are you?";
   }

    public function printOut() {
        echo $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";
//Fatal error: Abstract function AbstractClass::getValue() cannot contain body

4.从抽象类继承时,父类声明中标记为抽象的所有方法都必须由子类定义

如果继承抽象类,则必须为其中的所有抽象方法提供实现。

abstract class AbstractClass
{
    // Force Extending class to define this method
    abstract protected function getValue();

    // Common method
    public function printOut() {
        print $this->getValue() . "<br/>";
    }
}

class ConcreteClass1 extends AbstractClass
{
    public function printOut() {
        echo "dhairya";
    }

}
$class1 = new ConcreteClass1;
$class1->printOut();
//Fatal error: Class ConcreteClass1 contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (AbstractClass::getValue)

5.可见度相同(或限制较少)

从抽象类继承时,父类声明中标记为抽象的所有方法都必须由子类定义;此外,这些方法必须以相同(或限制较小)的可见性定义。例如,如果抽象方法被定义为受保护的,则函数实现必须定义为受保护的或公共的,而不是私有的。

注意,抽象方法不应该是私有的。

abstract class AbstractClass
{

    abstract public function getValue();
    abstract protected function prefixValue($prefix);

        public function printOut() {
        print $this->getValue();
    }
}

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_') ."<br/>";
//Fatal error: Access level to ConcreteClass1::getValue() must be public (as in class AbstractClass)

6.摘要方法的签名必须匹配

从抽象类继承时,父类声明中标记为抽象的所有方法都必须由子类定义;方法的签名必须匹配,即类型提示和所需参数的数量必须相同。例如,如果子类定义了一个可选参数,而抽象方法的签名没有,则签名中没有冲突。

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"), "<br/>";
echo $class->prefixName("Pacwoman"), "<br/>";
//output: Mr. Pacman
//        Mrs. Pacwoman

7.抽象类不支持多重继承

抽象类可以扩展另一个抽象类,抽象类可以提供接口的实现。但它不支持多重继承。

interface MyInterface{
    public function foo();
    public function bar();
}

abstract class MyAbstract1{
    abstract public function baz();
}


abstract class MyAbstract2 extends MyAbstract1 implements MyInterface{
    public function foo(){ echo "foo"; }
    public function bar(){ echo "bar"; }
    public function baz(){ echo "baz"; }
}

class MyClass extends MyAbstract2{
}

$obj=new MyClass;
$obj->foo();
$obj->bar();
$obj->baz();
//output: foobarbaz

注意:请注意代码中类的顺序或位置可能会影响解释器,并可能导致致命错误。因此,在使用多个抽象级别时,要注意类在源代码中的位置。

下面的例子将导致致命错误:找不到Class horse

class cart extends horse {
    public function get_breed() { return "Wood"; }
}

abstract class horse extends animal {
    public function get_breed() { return "Jersey"; }
}

abstract class animal {
    public abstract function get_breed();
}

$cart = new cart();
print($cart->get_breed());

扫码关注云+社区