SitePoint Sponsor

User Tag List

Results 1 to 16 of 16

Thread: Interface

Hybrid View

  1. #1
    PEACE WILL WIN abalfazl's Avatar
    Join Date
    Feb 2005
    Location
    Beyond the seas there is a town
    Posts
    711
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Interface

    Hello!

    http://www.artima.com/designtechniques/interfaces3.html


    interface Talkative {
    void talk();
    }
    abstract class Animal implements Talkative {
    abstract public void talk();
    }
    class Dog extends Animal {
    public void talk() {
    System.out.println("Woof!");
    }
    }
    class Cat extends Animal {
    public void talk() {
    System.out.println("Meow.");
    }
    }
    class Interrogator {
    static void makeItTalk(Talkative subject) {
    subject.talk();
    }
    }

    Given this set of classes and interfaces, later you can add a new class to a completely different family of classes and still pass instances of the new class to makeItTalk(). For example, imagine you add a new CuckooClock class to an already existing Clock family:


    class Clock {
    }
    class CuckooClock implements Talkative {
    public void talk() {
    System.out.println("Cuckoo, cuckoo!");
    }
    }

    Because CuckooClock implements the Talkative interface, you can pass a CuckooClock object to the makeItTalk() method:


    class Example4 {
    public static void main(String[] args) {
    CuckooClock cc = new CuckooClock();
    Interrogator.makeItTalk(cc);
    }
    }



    As You see,He adds new different family class and uses the interface.

    Is it possible to do that in PHP?
    I shall build a boat,I shall cast it in the water,
    I shall sail away from this strange earth,
    Where no one awaken the heroes in the wood of love

  2. #2
    SitePoint Enthusiast
    Join Date
    Aug 2006
    Posts
    41
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    yes, but you don't need to. The following code will work the same as above, but without the Interface and Abstract class.
    PHP Code:
    class Cat {
      public function 
    talk() {
        echo 
    "Meow";
      }
    }

    class 
    Dog {
      public function 
    talk() {
        echo 
    "woof!";
      }
    }

    class 
    Interrogator {
      public static function 
    makeItTalk($subject) {
        
    $subject->talk();
      }


  3. #3
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yuk!!

    You can do the same, although remember that with an abstraction, you cannot declare in an abstract class, a method to be abstract if it's declared within an implemented interface,

    PHP Code:
        interface QTalkative {
            public function 
    talk();
        }
        
        abstract class 
    QAnimal implements QTalkative {}
        
        final class 
    QDog extends QAnimal {
            public function 
    talk() {
                echo 
    'Woof!';
            }
        }
        
        final class 
    QCat extends QAnimal {
            public function 
    talk() {
                echo 
    'Meow!';
            }
        }
        
        final class 
    QInterrogator {
            static public function 
    makeItTalkQTalkative $subject ) {
                
    $subject -> talk(); // visitor
            
    }
        } 
    You'll notice in the base abstraction that I've removed the abstracted class method? If you require the class method to be abstract, don't put that class method in the interface declaration

  4. #4
    SitePoint Addict Jasper Bekkers's Avatar
    Join Date
    May 2007
    Location
    The Netherlands
    Posts
    282
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    PHP Code:
    abstract class QAnimal implements QTalkative {} 
    Why not just do this?

    PHP Code:
    interface QAnimal extends QTalkative {} 
    Design patterns: trying to do Smalltalk in Java.
    I blog too, you know.

  5. #5
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Jasper Bekkers View Post
    PHP Code:
    abstract class QAnimal implements QTalkative {} 
    Why not just do this?

    PHP Code:
    interface QAnimal extends QTalkative {} 
    Because "dog implements animal" would sound quite stupid, won't it?
    And what on the earth is "qanimal"?

    gjones example is the best. Never write more code than needed to get it to work.

    No, I'm not trying to inflame yet another "interfaces vs duck typing" holy war. I'd suggest forum search for "interface", the topic has been discussed far more than enough.

  6. #6
    SitePoint Addict Jasper Bekkers's Avatar
    Join Date
    May 2007
    Location
    The Netherlands
    Posts
    282
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by stereofrog View Post
    Because "dog implements animal" would sound quite stupid, won't it?
    And that doesn't sound like a good reason to waste your one shot at inheritance. I recently did a grep over my source files to see how often I actually use the extends keyword and the only two scenarios that involved that keyword were when I was required to use it because of a third-party or when doing "interface <foo> extends <bar>"

    And what on the earth is "qanimal"?
    They're really cute and furry

    gjones example is the best. Never write more code than needed to get it to work.
    That sound like we should all be coding cryptic stuff in perl.
    Design patterns: trying to do Smalltalk in Java.
    I blog too, you know.

  7. #7
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by stereofrog View Post
    gjones example is the best
    Even better:

    PHP Code:
    class Cat {

        function 
    talk() {
            echo 
    "Meow";
        }
    }
    class 
    Dog {

        function 
    talk() {
            echo 
    "woof!";
        }
    }
    class 
    Interrogator {

        function 
    makeItTalk($subject) {
            
    $subject->talk();
        }

    I'm firmly in the cut the clutter camp and public, private and protected don't really do anything useful either. Unless the code really needs to know something about itself hints etc just make it harder to read. That doesn't happen often.

  8. #8
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by McGruff View Post
    Unless the code really needs to know something about itself hints etc just make it harder to read. That doesn't happen often.
    It makes it easier to change the interface. If a method is declared private or protected, it's fairly easy to rename the method, because you have a limited number of places to look for. With a public method, you could potentially break any part of your application.

    On the same note, I've found myself using typehints more recently - And as a consequence of that, interfaces (Since typehinting to a class is a hard coupling). Maybe it's just a phase I'm going through.

  9. #9
    SitePoint Wizard bronze trophy devbanana's Avatar
    Join Date
    Apr 2006
    Location
    Pennsylvania
    Posts
    1,736
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kyberfabrikken View Post
    On the same note, I've found myself using typehints more recently - And as a consequence of that, interfaces (Since typehinting to a class is a hard coupling). Maybe it's just a phase I'm going through.
    I also feel more comfortable using type hinting, though it's probably my preference of strongly typed languages.

    I just can't bear having a parameter that I plan to call a method on, and having no ensurance that that method actually exists in that object. For example if Talkative is explicitly hinted in the parameter of makeItTalk(), I can be sure that talk() exists. Otherwise any old object could be passed and I couldn't be sure if it implemented that method.

    As for the way to implement this in PHP, it'd be the same as in Java I guess. Whether I would have a separate talkative interface depends if other things besides animals need to talk. Also whether I would have an animal class at all depends if I really ever care if it's an animal, or just ever want to know if it can talk or not.

    If both the above are true then yes, I would have a Talkative interface implemented by an animal abstract class. That's maximum flexibility; but you need to be careful not to take that too far. It'd be pretty absurd to have a Walker interface for animals too, for example.
    Laudetur Iesus Christus!
    Christ's Little Flock
    Jesus is the Good Shepherd

  10. #10
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You could do that I suppose, but I was just going by the example posted

    However when it comes to extending on an interface I would only do so if there were commonality that could be shared, so not to introduce duplication, for example,

    PHP Code:
    interface QAction_Handler_Interface extends QComposite_Interface {} 
    The typeof QComposite is an abstraction so I could just as well use the abstraction, instead of using a separate interface, but with PHP (and quite rightly so) you only get one shot with inheritance.

    This way, I can still declare QAction_Handler_* as a typeof QComposite but have the ability to allow QAction_Handler_* extend if I ever have to

    So you see... You have greater freedom with interfaces than you do with an abstraction but you know that already

  11. #11
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    > Maybe it's just a phase I'm going through.

    Did you think at the time, your design will be more flexible because of this? Or do you precieve your design is more flexible Kyber?
    Last edited by Dr Livingston; Jul 29, 2007 at 06:42.

  12. #12
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Dr Livingston View Post
    > Maybe it's just a phase I'm going through.

    Did you think at the time, your design will be more flexible because of this? Or do you precieve your design is more flexible Kyber?
    I don't think typehints makes the code more flexible. Perhaps even the opposite. The value, it's adding is clarity. When you write very composite code, where there are multiple objects working together to produce a result, it can be hard to follow, where each part plugs into. By using typehints, it becomes obvious how the puzzle should be assembled. There are other ways to accomplish this, but since there is language level support for typehints, it seems more appropriate to use, than a userland solution. This of course is the same argument, McGruff makes about dependency injection containers, but I think it applies to manual assembly as well as automatic.

  13. #13
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Umm...

    > but since there is language level support for typehints, it seems more appropriate to
    > use, than a userland solution.

    This is how I looked at it when PHP5 was first launched; I didn't just want to develop with PHP but I wanted to support it as well. Since then though, I've grown accustomed to using type hints in near 99&#37; of my scripts.

    There are a few places where I don't use type hints, although it's not common, for example here,

    PHP Code:
    // ...
    public function validateQDataspace_Interface $request$logger ) { ... 
    And here...

    PHP Code:
    // ...
    public function push$acceptable ) { ... 
    It makes sense not to put a type hint here for the $logger since there may be an occasion where I need to pass in something that would break the interface... But in saying that my framework is pretty much structurally sound, so it's more uncommon for me to do something like this, rather than be it more common (not to use type hints).

    As to flexibility, I still think the flexibility is still there provided the underlying structure has been well thought out, using type hints.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •