The differences are theoretical and practical:
- an interface is a description of some of the features that your class has and advertises (therefore, different classes that implement the same interface can be used the same way)
- An abstract class can be a default implementation containing parts that can appear in all implementations. It should not implement the full interface.
An example is the interface:
// 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(); }
Now we have a set of requirements that will be checked for each class that implements this. Let me make an abstract class and its children:
// 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'; } }
A completely different abstract class (not associated with an interface), with a subclass that implements our interface:
abstract class AbstractDog { function bark() { return 'Woof!'; } } class GoldenRetriever extends AbstractDog implements IRetrieveData {
Now, in another code, we can do this:
function getStuff(IRetrieveData $retriever, $url) { $stuff = $retriever->fetch($url); }
and we donβt need to worry about which retriever (cURL, PHP or Golden) will be passed on and how they will achieve the goal, since everyone should be able to behave in a similar way. You can do this with an abstract class, but then you limit yourself based on the ancestors of the classes, not its capabilities.
source share