views:

78

answers:

6

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

hi guys..

As far as I understand, a clase 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. Can anyone explain which one to use in real life project and the difference? Thanks a million!!!!

+1  A: 
"An Abstract Class can contain default Implementation, where as an 
Interface should not contain any implementation at all. "

As far as which to use in real world application... it really comes down to context.

For example, there was a question on here the other day about implementing a game using PHP. Here they had a abstract class defining a monster and any monster could be based off of this abstract class. This allowed for inheritance of default monster properties.

Whereas for an interface, you are defining a general requirements for a way to "interface" (pardon using the term in the explanation) some system. An example of this from a recent project I did. I implemented a soapclient in php to interact with a soapserver from a third party. This interface defines what soap methods the server supports and thus any class implementing my interface must define those methods.

Chris
+3  A: 

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.

Piskvor
Ty for the example....+1
Jerry
@Jerry: You're welcome.
Piskvor
+2  A: 

Multiple vs. single inheritance:

  • You can only inherit from a single abstract class
  • You can inherit from 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.

haydenmuhl
+1  A: 

Here's a good description of the differences between the two:

http://www.supertom.com/code/php_abstracts_and_interfaces.html

It all boils down to the fact that extends is a "is-a" relationship while implements is a "has-a" relationship.

js1568
+1  A: 

The metaphor I heard best was that an abstract class is a half-completed class. It's not done; you still have to finish it. So when you make a class that extends an abstract class, you are just completing what you began in the abstract class. This is also why you can't instantiate an abstract class; that you've made it abstract indicates that it's incomplete. It still needs some additional functionality.

An an interface just guarantees that certain methods, each with a certain number of arguments, must exist within a class that implements it. So that later on, a programmer who uses a class that implements a particular interface can rest assured that they can call certain methods on that class.