tags:

views:

54

answers:

1

from what i've read it seems that one can interact with an interface?

eg. lets say that i've got an interface with an empty method "eat()"

then 2 subclasses are implementing this interface.

can my controller interact with only the interface and use it's eat() method?

have a look at the picture in this link strategy

+3  A: 

You cannot interact with an interface except for accessing any defined constants in it or using it for TypeHints. Interfaces do not have method bodys. They are solely meant to define a contract implementing classes must obey.

interface Logger
{
    const FOO = 1;
    public function log($msg);
}

echo Logger::FOO;  // 1
Logger::log($msg); // Fatal error: Cannot call abstract method Logger::log()
new Logger;        // Fatal error: Cannot instantiate interface Logger

See http://de3.php.net/manual/en/language.oop5.interfaces.php


What is generally meant when coding against an interface or interacting with an interface is basically nothing more than calling methods defined in an interface in the classes implementing them. You call the implementation, not the definition. The definition just specifies that for every Class implementing the interface, there has to be a specific method with the specified arguments.

Consider these classes:

Class DbLog implements Logger 
{
    public function log($msg) { /* log $msg to database */ }
}

Class FileLog implements Logger
{
    public function log($msg) { /* log $msg to file */ }
}

Both classes implement Logger and therefor have to have a method log($msg). You're basically saying: "hey class, if you want be a Logger, make sure I can call log() on you.". Now somewhere in your code you might have a class that needs a logger, like

class Foo
{
    protected $logger;
    public function __construct(Logger $logger)
    {
        $this->logger = $logger;
        $this->logger->log('I can haz logger! Yay!');
    }
}

Foo doesn't care if it gets FileLog, DbLog or any other concrete Logger. It just cares that it gets any Logger it can call log() on. Foo isn't even interested in what log() does. All Foo cares about is being able to call log(). You're not calling log() in the interface though. You are calling it in the conrete class that was passed to Foo, but in an UML diagram you'd represent this like it's shown in the page you linked, because you just coded against an interface.

The main advantage of this is that your classes are much less coupled. You can more easily swap out dependencies, for instance when using Mocks in unit-testing, and your code will be more maintainable.

Basically, think of an interface as a conceptual standardization. For instance, when you buy a new DVD Player, you expect it to have a button that somehow (you don't care how, just that) makes the player play the DVD. When you press that button, you're not pressing the general abstract DVD interface specification that says a DVD player must have a play button, but you clicked the concrete implementation of a play button on this brand of player.

Gordon
u've look at the link i posted? i thought the "context" it was interacting with the interface
never_had_a_name
@ajsie yes, actually, I'm the guy who is littering SO with the sourcemaking links, so you likely found it through one of my posts :) The idea of the interface is just to provide the API, not the implementation. If anything, it is an indirect interaction. Check out this answer of mine: http://stackoverflow.com/questions/1957732/can-i-include-code-into-a-php-class/1957830#1957830
Gordon
i think i did...u r everywhere! :) there are really good design pattern reference for java in www.developers.com, covering every design pattern with code examples. do you know such reference page for php? it would be very helpful. but i cant find any.
never_had_a_name
@ajsie You'd have to specify which patterns you're after. Sourcemaking covers all GOF patterns. There is some more links below the linked answer. Often referenced is http://martinfowler.com/eaaCatalog/index.html, but that's UML only.
Gordon
yeah sourcemaking covered them but not with php code. "php design patterns" by schmidt seems like a good book with examples.
never_had_a_name
@ajsie not sure I understand, for all patterns on sourcemaking there is php code linked at the bottom of the pages. The book by Schmidt is great. I think it is only available in german though. If you can read german, buy it. Has been updated recently for 5.3 too. See http://www.phpdesignpatterns.de/auflage-2/
Gordon
wow..didnt see that..php code for every design pattern! thanks! now im twice as happy:) didnt know the book was in german, thought i read the TOC in english? how else could i have read it? hmm...i'll check and come back with answer.
never_had_a_name
@gordon. can u have a look at this one: http://stackoverflow.com/questions/2697783/program-to-interfaces-not-implementations. they are talking about Interfaces and how you should interact with them and not the subclasses that hold the implementations. these things are giving me a feeling that you can interact with an interface. but what do they mean? could you give an easy code example or a tutorial for this? has bugged me a long time not to know
never_had_a_name
@ajsie update answer. Hope it's clearer now.
Gordon
@gordon. thanks for great explanation. just some questions. all this require that you know which classes implements the specific interface you are interested in. so if im coding all this, does it means that i have to create a UML class diagram and specify which classes are implementing an interface. then i know i can throw either one of these concrete classes into Foo class. the usefulness of this relies on a UML diagram right? and why doesnt an interface specify wether or not a method should return anything. cause now the implementation classes don't know if they should return or not return.
never_had_a_name
@ajsie UML is completely independent from PHP. You don't need either for the other. Sourcemaking has tutorials on UML if you want to learn how to read it though. Return values cannot be specified in an interface, simply because PHP has no way to declare a return value in a method signature at all. You can use PHPDocs @return annotation to indicate what it should return as a hint for developers reading your code.
Gordon