关于oop:什么是PHP中的抽象类?

what is abstract class in php?

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


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

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

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

请参阅本节的PHP手册以获取进一步的参考。


Abstract classes are classes that contain one or more abstract methods. An abstract method is a method that is declared, but contains no implementation. Abstract classes may not be instantiated, and require subclasses to provide implementations for the abstract methods.

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

下面的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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。任何包含至少一个抽象方法的类也必须是抽象的:抽象类可以有抽象方法和非抽象方法,但必须至少包含一个抽象方法。如果一个类至少有一个抽象方法,那么该类必须声明为抽象的。

Note: Traits support the use of abstract methods in order to impose requirements upon the exhibiting class.

下面的例子:

1
2
3
4
5
6
7
8
9
10
11
12
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)

三。抽象方法不能包含body:定义为abstract的方法只声明方法的签名-它们不能定义实现。但非抽象方法可以定义实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
abstract class AbstractClass
{
   abstract protected function getValue(){
   return"Hello how are you?";
   }

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

4。从抽象类继承时,父类声明中标记为abstract的所有方法都必须由子类定义:如果继承抽象类,则必须为其中的所有抽象方法提供实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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的所有方法都必须由子级定义;此外,这些方法必须使用相同(或限制较少)的可见性定义。例如,如果将抽象方法定义为Protected,则必须将函数实现定义为Protected或Public,但不能定义为Private。

Note that abstract method should not be private.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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的所有方法都必须由子类定义;方法的签名必须匹配,即类型提示和所需参数的数目必须相同。例如,如果子类定义了一个可选参数,而抽象方法的签名没有,则签名中没有冲突。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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。抽象类不支持多重继承:抽象类可以扩展另一个抽象类,抽象类可以提供接口的实现,但不支持多重继承。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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

Note: Please note order or positioning of the classes in your code can affect the interpreter and can cause a Fatal error.
So, when using multiple levels of abstraction, be careful of the positioning of the classes within the source code.

以下示例将导致致命错误:未找到类"horse"

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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());


An abstract class is a class that is
only partially implemented by the
programmer. It may contain one or more
abstract methods. An abstract method
is simply a function definition that
serves to tell the programmer that the
method must be implemented in a child
class.

这里有很好的解释。


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

抽象方法
1。不能包含正文
2。不能定义为private
三。子类必须定义抽象类中声明的方法

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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/>";

输出:

1
2
3
4
5
Hello World
India
Hello World test
F1 Method Call
F2 Method Call


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

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

另外,要成为一个抽象类,至少一个类的方法必须是抽象的。

关于抽象类的详细信息,可以参考我在PHP中关于抽象类的博客。