什么是 PHP 中的抽象类?

什么是 PHP 中的抽象类?

怎么用?

115872 次浏览

一个抽象类是一个 部分实施 它可能包含一个或多个 抽象方法 只是一个函数定义 用来告诉程序员 方法必须在子级中实现 同学们。

有很好的解释 在这里

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

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

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

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

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

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

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

注意: Traits 支持使用抽象方法,以便对显示类施加要求。

例如:

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.抽象方法不能包含 body : 定义为抽象的方法只是声明方法的签名——它们不能定义实现。但是一个非抽象的方法可以定义实现。

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.相同(或限制较少)的可见性 : 当从抽象类继承时,父类声明中标记为抽象的所有方法必须由子类定义; 另外,这些方法必须用相同(或限制较少)的可见性定义。例如,如果将抽象方法定义为 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.抽象类不支持多重继承 : 抽象类可以扩展另一个抽象类,抽象类可以提供接口的实现。但它不支持多重继承。

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. 包含一个抽象方法
无法直接初始化
3. 无法创建抽象类的对象
4. 仅用于继承目的 < br/>

抽象方法
1. 不能容纳物体
2. 不能定义为私有
子类必须定义在抽象类 < br/>

中声明的方法

示例代码:

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

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

抽象方法是指一个没有定义的空方法,因此只有一个不同的抽象类,我们不能创建一个对象的抽象类

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