Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between abstract and interface in php? [duplicate]

Possible Duplicate:
PHP: What is the difference between an interface and abstract class?

As far as I understand, a class implements or extends abstract or interface class has to use the default methods. I know we can use implement keyword to use multiple interfaces, but we only can extend 1 abstract. Which one to use in real life project and the difference?

like image 607
FlyingCat Avatar asked Aug 26 '10 16:08

FlyingCat


2 Answers

The differences are both theoretical and practical:

  • interface is a description of some capability your class has and advertises (so various classes implementing the same interface can be used the same way)
  • abstract class can be a default implementation, containing the parts which are likely to appear in all the implementations. It doesn't have to implement the complete interface

Example - an 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 the set of requirements that will be checked for every class implementing this. Let's 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 (unrelated to the interface), with a subclass which implements our interface:

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();
     }
}

Now, in other code, we can do this:

function getStuff(IRetrieveData $retriever, $url) {
    $stuff = $retriever->fetch($url);
}

and we don't have to worry which of the retrievers (cURL, PHP, or Golden) will be passed in, and how are they going to accomplish the goal, as all should be capable of behaving similarly. You could do this with an abstract class, too, but then you're restricting yourself based on the classes' ancestor, instead of its capability.

like image 182
Piskvor left the building Avatar answered Oct 13 '22 01:10

Piskvor left the building


Multiple vs. single inheritance:

  • You can only inherit from a single abstract class
  • You can implement multiple interfaces

Implementation:

  • An abstract class can actually have functioning code in it. This lets you share implementation between the child classes
  • An interface only defines public member functions. Classes implementing the same interface don't actually share code.

That's what I know off the top of my head.

like image 35
haydenmuhl Avatar answered Oct 13 '22 01:10

haydenmuhl