可能重复:
PHP: What is the difference between an interface and abstract class?
嗨伙计..
据我所知,一个clase实现或扩展abstract或接口类必须使用默认方法。我知道我们可以使用implement关键字来使用多个接口,但我们只能扩展1个抽象。任何人都可以解释在现实生活中使用哪一个项目和区别?万分感谢!!!!
答案 0 :(得分:11)
区别在于理论和实践:
示例 - 界面:
// define what any class implementing this must be capable of
interface IRetrieveData {
// retrieve the resource
function fetch($url);
// get the result of the retrieval (true on success, false otherwise)
function getOperationResult();
// what is this class called?
function getMyClassName();
}
现在我们已经为每个实现此目的的类检查了一系列需求。让我们创建一个抽象类及其子类:
// define default behavior for the children of this class
abstract class AbstractRetriever implements IRetrieveData {
protected $result = false;
// define here, so we don't need to define this in every implementation
function getResult() {
return $result;
}
// note we're not implementing the other two methods,
// as this will be very different for each class.
}
class CurlRetriever extends AbstractRetriever {
function fetch($url) {
// (setup, config etc...)
$out = curl_execute();
$this->result = !(curl_error());
return $out;
}
function getMyClassName() {
return 'CurlRetriever is my name!';
}
}
class PhpRetriever extends AbstractRetriever {
function fetch($url) {
$out = file_get_contents($url);
$this->result = ($out !== FALSE);
return $out;
}
function getMyClassName() {
return 'PhpRetriever';
}
}
一个完全不同的抽象类(与接口无关),带有实现我们接口的子类:
abstract class AbstractDog {
function bark() {
return 'Woof!';
}
}
class GoldenRetriever extends AbstractDog implements IRetrieveData {
// this class has a completely different implementation
// than AbstractRetriever
// so it doesn't make sense to extend AbstractRetriever
// however, we need to implement all the methods of the interface
private $hasFetched = false;
function getResult() {
return $this->hasFetched;
}
function fetch($url) {
// (some retrieval code etc...)
$this->hasFetched = true;
return $response;
}
function getMyClassName() {
return parent::bark();
}
}
现在,在其他代码中,我们可以这样做:
function getStuff(IRetrieveData $retriever, $url) {
$stuff = $retriever->fetch($url);
}
并且我们不必担心将传入哪些检索器(cURL,PHP或Golden),以及它们如何实现目标,因为所有检索器都应该具有相似的行为。您也可以使用抽象类来完成此操作,但是您根据类的祖先而不是其功能来限制自己。
答案 1 :(得分:6)
多重与单一继承:
实现:
这就是我所知道的。
答案 2 :(得分:2)
我听到最好的比喻是抽象类是半完成的类。它没有完成;你仍然需要完成它。因此,当您创建一个扩展抽象类的类时,您只是完成了您在抽象类中开始的内容。这也是你无法实例化抽象类的原因;你把它做成抽象表明它是不完整的。它仍然需要一些额外的功能。
接口只保证某些方法必须存在于实现它的类中,每个方法都有一定数量的参数。因此,稍后,使用实现特定接口的类的程序员可以放心,他们可以在该类上调用某些方法。
答案 3 :(得分:1)
"An Abstract Class can contain default Implementation, where as an
Interface should not contain any implementation at all. "
至于在现实世界的应用程序中使用哪个......它实际上归结为上下文。
例如,有一个question on here the other day about implementing a game using PHP。在这里,他们有一个定义怪物的抽象类,任何怪物都可以基于这个抽象类。这允许继承默认的怪物属性。
对于接口,您正在定义一种对“接口”(使用解释中的术语)某种系统的方法的一般要求。我最近的一个项目就是一个例子。我在php中实现了一个soapclient来与第三方的soapserver进行交互。此接口定义服务器支持的soap方法,因此实现我的接口的任何类都必须定义这些方法。
答案 4 :(得分:1)
答案 5 :(得分:1)
以下是对两者之间差异的一个很好的描述:
http://www.supertom.com/code/php_abstracts_and_interfaces.html
这一切都归结为这样一个事实:extends是一个“is-a”关系,而implements是一个“has-a”关系。