什么是抽象类和接口,何时在PHP中使用它们?

时间:2010-09-15 22:17:39

标签: php oop cakephp codeigniter

PHP中的抽象类和接口是什么?何时使用它们?一个外行人回答一个例子对我的理解很有帮助。

5 个答案:

答案 0 :(得分:7)

抽象类和接口不是特定于PHP的;它们是许多现代面向对象语言的特征。

抽象类是具有一个或多个未实现的成员函数的类。您可以在需要一组具有相似行为的类的情况下使用一个,仅在少数方法中有所不同。这些类中的每一个都派生自抽象类,并以适合其特定情况的方式实现未实现的方法。

接口类似于抽象类,但它不包含任何方法实现,只包含签名。实现接口的类必须实现所有方法。

一个类可以实现许多接口,但只能从一个抽象类(或任何类型的父类)派生,因为PHP不支持多重继承。

抽象类和接口都允许多态;即,您可以将引用指定为抽象类型(可以引用从中派生的类的任何实例)或实现接口的对象。

答案 1 :(得分:4)

假设您理解为何在其他语言中使用它们,则相同的概念适用于PHP。接口是类“签名”......它们不包含代码。抽象类不能实例化,但它们可以包含实现和抽象(空)函数。

请注意,类只能扩展单个父类(或抽象类),但它可以根据需要实现任意数量的接口。

但鉴于PHP没有严格的输入并且没有编译时间检查的概念,你可以通常不使用它们,这与C ++或Java等语言不同。

核心PHP需要某些东西的接口。例如:

class Foo implements Countable
{
  public function count()
  {
    return 5;
  }
}

echo count(new Foo()); // returns 5

如果删除“implements Countable”,PHP将不会调用您的count方法。您可以实现许多其他接口,允许自定义对象以类似的方式运行。例如,您可以创建一个使用foreach迭代的对象。

用户级别的接口在PHP中并不是非常有用,正如我之前提到的那样。但是如果你使用类型提示,它们可以是:

function foo(MyInterface $bar)
{
  $bar->someMethod();
}

假设someMethod中声明MyInterface,则可以保证对$bar->someMethod()的调用存在。 (之所以这在PHP中并不像在其他语言中那样有用,是因为函数签名中的类型提示在运行时才会被检查。)

空接口也可用作分类类的方法。假设您想对特定的一组对象执行某些操作。他们都可以实现一些空接口。然后你的代码可以检查该接口,而不必知道关于该对象的任何信息。

interface Red {}

class Foo implements Red { }

$foo = new Foo();
if ($foo instanceof Red)
{
  // do something
}

当你有很多在子类之间共享的代码时,抽象类很有用,但它本身没有意义。您可以将基类声明为抽象,实现所有共享功能,并将其余功能保留为空。通过将基类声明为抽象,没有人能够自己使用它。

答案 2 :(得分:1)

PHP手册简单解释并提供了许多示例:

答案 3 :(得分:1)

答案 4 :(得分:0)

接口定义了一个类必须实现的一组方法。这样的类通过提供这些方法的具体实现来实现接口。接口不能包含自己的任何实现;它只是一组方法签名。如果我定义了一个名为ILogger的接口,那么我可以编写使用ILogger(可能是writewriteLine)中定义的方法的代码来传递要记录的消息。我可以传入任何实现ILogger的类,并且它与客户端代码完全相同。

抽象类类似,但可以实现一些方法和状态。抽象类无法实例化,任何扩展它们的类都必须提供父类中每个abstract方法的实现。如果一组类共享一些实现细节但在其他类中有所不同,那么您可以在抽象类中定义共享实现,声明不同的方法abstract,并让子类用自己的实现填充它们。如果我想要一种统一的方式来收集系统信息,添加我的所有记录器共享的时间戳等,我可能会选择创建一个处理这些细节的抽象类LoggerBase,标记为write和{ {1}} writeLine以便任何扩展abstract的类只需指定如何写入其特定日志。