可能重复:
PHP:接口和抽象类有什么区别? 据我所知,实现或扩展抽象或接口类的类必须使用默认方法。 我知道我们可以使用实现关键字来使用多个接口,但是我们只能扩展1个抽象类。 在实际项目中应该使用哪一个以及它们之间的区别是什么?
PHP:接口和抽象类有什么区别? 据我所知,实现或扩展抽象或接口类的类必须使用默认方法。 我知道我们可以使用实现关键字来使用多个接口,但是我们只能扩展1个抽象类。 在实际项目中应该使用哪一个以及它们之间的区别是什么?
这些差异既有理论上的,也有实践上的:
interface
是描述类具有和广告的某些 能力(因此,实现相同接口的各种类可以以相同的方式使用)。abstract class
可以是一个默认实现,包含可能出现在所有实现中的部分。它不必实现完整的接口。例如- 一个接口:
// 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)将被传递以及它们将如何实现目标,因为所有检索器都应该能够表现出类似的行为。您也可以使用抽象类来实现此功能,但这样做会限制您基于类的祖先而不是其能力。
多重继承 vs 单一继承:
实现:
这就是我记得的内容。
"An Abstract Class can contain default Implementation, where as an
Interface should not contain any implementation at all. "
关于在实际应用中使用哪种语言,这真的取决于上下文。
例如,这里有一个问题,关于如何使用PHP实现游戏。在这里,他们定义了一个抽象类来定义怪物,任何怪物都可以基于这个抽象类。这允许默认怪物属性的继承。
而对于接口,您正在定义一种“接口”的通用要求(请原谅我在解释中使用该术语)。我最近做的一个项目就是实现了一个php中的soapclient,以与第三方的soapserver进行交互。此接口定义了服务器支持的soap方法,因此实现我的接口的任何类都必须定义这些方法。
http://www.supertom.com/code/php_abstracts_and_interfaces.html
归根结底,extends是“is-a”关系,而implements是“has-a”关系。