Различия как теоретические, так и практические:
- интерфейс является описание некоторых возможностей ваш класс имеет и рекламирует (так различные классы, реализующие один и тот же интерфейс может быть использован один и тот же путь)
- абстрактным классом может быть по умолчанию реализация, содержащая части, которые могут появиться во всех реализациях. Это не необходимо реализовать полный интерфейс
Пример - интерфейс:
// 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);
}
, и мы не должны беспокоиться, какой из поисковиков (локон, PHP, или Золотой) будут переданы в, и как они собираются достичь цели, так как все Shou ld быть способным вести себя аналогичным образом.Вы можете сделать это и с абстрактным классом, но тогда вы ограничиваете себя на основе предков классов, а не его возможностей.
Duplicate: http://stackoverflow.com/questions/1913098/php-what-is-the-difference-between-an-interface-and-abstract-class – shamittomar
вопрос может быть обобщен, возможно ... :) – ultrajohn