什么是PHP中的抽象类?


121

什么是PHP中的抽象类?

如何使用?




6
@戈登:有时某些人的官方文档不是很清楚:(
Sarfraz 2010年


3
@Sarfraz不是RTFM方式。我只是认为链接到官方文档是有用的资产。而且您不会相信会有多少人不阅读官方文档,甚至不知道它们存在。
Gordon

Answers:


131

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

这样做的目的是提供一种模板,以从其继承并强制继承类实现抽象方法。

因此,抽象类介于常规类和纯接口之间。接口也是抽象类的特殊情况,其中所有方法都是抽象的。

有关更多参考,请参见PHP手册的这一部分


6
此线程中,抽象不包含任何抽象方法。
r0ng

6
@ r0ng说一个抽象类可能包含抽象方法,并且抽象方法必须始终在抽象类内部,这将是更正确的说法。在我看来,定义的实用功能是不能实例化抽象类,但可以继承和覆盖方法,并且可以正常使用抽象类中的静态方法。
okdewit

117

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

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.任何至少包含一个抽象方法的类也必须是抽象的:抽象类可以具有抽象和非抽象方法,但是它必须至少包含一个抽象方法。如果一个类至少具有一个抽象方法,则必须将该类声明为abstract。

注意:特性支持抽象方法的使用,以便对展示类强加要求。

下面的例子:

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的所有方法都必须由子代定义:如果继承一个抽象类,则必须为其中的所有抽象方法提供实现。

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.相同(或较少限制)的可见性:从抽象类继承时,父类声明中标记为抽象的所有方法必须由子代定义;此外,必须以相同(或较少限制)的可见性定义这些方法。例如,如果抽象方法定义为protected,则函数实现必须定义为protected或public,但不能定义为private。

请注意,抽象方法不应为私有方法。

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. Abstract类不支持多重继承:Abstract类可以扩展另一个Abstract类,Abstract类可以提供接口的实现。但是它不支持多重继承。

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 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());

1
好好阐述。
Talk2Nit

18

抽象类是仅由程序员部分实现的类。它可能包含一个或多个抽象方法。抽象方法只是一个函数定义,用于告诉程序员该方法必须在子类中实现。

还有的是很好的解释在这里


嗨,谢谢您的解释,事实是,在Internet上没有关于PHP中的抽象和接口的很好的解释。
列宁·萨帕塔

12

抽象类
1.包含抽象方法
2.无法直接初始化
3.无法创建抽象类的对象
4.仅用于继承目的

抽象方法
1.无法包含主体
2.无法定义为私有
3.子类必须定义在抽象类中声明的方法

示例代码:

abstract class A {
    public function test1() {
        echo 'Hello World';
    }
    abstract protected function f1();
    abstract public function f2();
    protected function test2(){
        echo 'Hello World test';
    }
}

class B extends A {
    public $a = 'India';
    public function f1() {
        echo "F1 Method Call";
    }
    public function f2() {
        echo "F2 Method Call";
    }
}

$b = new B();
echo $b->test1() . "<br/>";
echo $b->a . "<br/>";
echo $b->test2() . "<br/>";
echo $b->f1() . "<br/>";
echo $b->f2() . "<br/>";

输出:

Hello World
India
Hello World test
F1 Method Call
F2 Method Call

您不能通过子类对象调用父级受保护的方法,而可以通过该对象调用子类方法echo $ b-> test2()。“ <br/>”;
Al-Amin

7
  • 抽象类仅包含声明方法的签名,而不能定义实现。
  • 抽象类使用关键字abstract定义。
  • 抽象类不可能实现多重继承
  • 最新版本的PHP 5引入了抽象类和方法。
  • 定义为abstract的类,我们无法创建对象(可能无法实例化)

0

抽象类是那些不能直接初始化的类。换句话说,我们可以说抽象类是那些不能直接创建对象的类。在PHP中,抽象类用关键字abstract定义

同样要成为一个抽象类,该类的一种方法必须是抽象。

有关抽象类的详细信息,请参阅我的PHP抽象类博客。


0

抽象类就像普通类一样,它包含变量,它包含受保护的变量函数,它包含构造函数,只有一点不同,它包含抽象方法。

抽象方法意味着没有定义的空方法,因此抽象类中只有一个区别,我们无法创建抽象类的对象

抽象必须包含抽象方法,并且这些方法必须在其继承类中定义。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.