Interface freeloading on a superclass - is it good practice?

Discussion in 'Java' started by Chris Berg, Aug 15, 2005.

  1. Chris Berg

    Chris Berg Guest

    This appears to be legal:

    public interface MyInterface {
    void setEnabled(boolean enabled);
    }

    public class MyComponent extends java.awt.Component
    implements MyInterface {
    // setEnable() NOT implemented, 'cause it comes with Component
    }

    It compiles and runs, although it appears to me there is something
    conceptually wrong. Shouldn't 'implemeting an interface' mean just
    that, not freeloading on some superclass?

    And will it always work, on any version of VM?

    Some techniques can be technically ok but still considered bad
    programming practice. What about this one?


    Chris
     
    Chris Berg, Aug 15, 2005
    #1
    1. Advertisements

  2. It depends.

    If setEnable() in Component satisfies the intention of MyInterface,
    then I don't see a problem.
     
    Monique Y. Mudama, Aug 15, 2005
    #2
    1. Advertisements

  3. Chris Berg

    bugbear Guest

    In the case of "Adapters" it's the entire purpose
    of the superclass.

    http://www.wdvl.com/Authoring/Scripting/Tutorial/java_adapters.html

    Sadly, the "Pattern Book" uses the word Adapter to mean something
    utterly different.

    BugBear
     
    bugbear, Aug 15, 2005
    #3
  4. If not there would be something fundamentally wrong with the jvms that
    (don't) run the program.
    Can you think of any other way? To me it seems you want to utilize the
    interface mechanism to structure your program. Sounds like good
    programming practice to me ... The only thing I'd change is the name of
    MyInterface, I'd call it Enableable ;-)
     
    Jon Martin Solaas, Aug 15, 2005
    #4
  5. Chris Berg

    Chris Berg Guest

    I see the point, but I think that's not completely the same situation.

    The normal use of Adapter is:

    class MyClass extends MouseAdapter { ...

    not

    class MyClass extends MouseAdapter implements MouseListener { ...

    The last example is what resembles mine. It will compile, but it
    claims to implement the interface without necessarily doing it.
    MouseAdapter and MouseListener has exactly the same methods, which is
    why 'implements MouseListener' is ambiguous, but that is not the case
    in my example. So anyoune reading the code would get confused.

    Well, as I said, it works tecnically, I just wondered if it was
    considered good practice...

    Chris
     
    Chris Berg, Aug 15, 2005
    #5
  6. Jon Martin Solaas wrote:
    ....
    I can think of another way, I just consider it inferior.

    public class MyComponent extends java.awt.Component implements Enableable{
    void setEnabled(boolean enabled){
    super.setEnabled(enabled);
    }
    }

    Of course, it leads to a lot of junk code, and brings no benefit because
    an inherited setEnabled is just as much a member of MyComponent as one
    declared in the class body.

    Patricia
     
    Patricia Shanahan, Aug 15, 2005
    #6
  7. Chris Berg

    Chris Berg Guest

    Well, it's really not a purely academic discussion. Here is an excerpt
    from the actual program:

    public interface IToolButton{
    boolean isSelected();
    void setSelected(boolean selected);
    void click();
    void setEnabled(boolean enabled); // inherited from Component
    void repaint();
    void toggleSelected();
    int getID();
    void setActive(boolean active);
    void setVisible(boolean visible);
    void invalidate();
    void validate();
    boolean isDoubleClick();

    }

    An IToolButton CAN be implemented by a lightweight java.awt.Component,
    but it can also be implemented by something else, for instance by
    interfacing to some JavaScript code. The rest of the program treats
    any implementation solely as an IToolButton (good practice!), and if I
    implement it NOT using a java.awt.Component, I will have to supply all
    the methods, most of which come free in Component.

    Chris
     
    Chris Berg, Aug 15, 2005
    #7
  8. Chris Berg

    jan V Guest

    Some techniques can be technically ok but still considered bad
    You highlight a not-so-happy facet of Java (it's hard to think of everything
    when you design something as complex as a general purpose language.....).

    The pragmatic solution is not to do what you highlighted. And to avoid any
    accidental situations like the one highlighted, you should choose your
    interface method names with care. Knowing a few thousand core API method
    names helps to avoid collisions ;-)
     
    jan V, Aug 15, 2005
    #8
  9. Chris Berg

    jan V Guest

    Well, it's really not a purely academic discussion. Here is an excerpt
    It does look a bit like you're trying hard to bend reality to fit some
    strange "clever" scheme which may be more trouble than it's worth, in the
    long run. As with many apparently-clever schemes, this one smells of
    potential problems: say that Sun, in their infinite wisdom, decide that one
    or more of the methods you've "hijacked" in your interface need
    reimplementing, possibly with their functionality subtly changed. Suddenly
    your clever interface scheme breaks... and you're desperately forced to
    patch the new AWT or Swing component (by overriding the newly "misbehaving"
    methods) to behave the way your interface expects a subset of AWT/Swing
    component methods to behave. These patches may be impossible to write, in
    which case you'll be forced to rename some of your interface methods, which
    in turn will force you to implement those methods you previously believed to
    come "for free" in Component, etc..

    So all in all, unless my prediction of trouble ahead is flawed, I think you
    need to go back to the drawing board on this one.,..
     
    jan V, Aug 15, 2005
    #9
  10. Chris Berg

    Oliver Wong Guest

    Anytime the behaviour of a publicly expose method (whether written by
    Sun or anyone else) changes, then there's the possibility that someone or
    something using that method will break.

    That's a fundamental weakness in OOP, though as far as I know, no other
    paradigm exists that can address this weakness.

    - Oliver
     
    Oliver Wong, Aug 15, 2005
    #10
  11. Chris Berg

    Oliver Wong Guest

    Yeah, this is a weakness in Java (name collisions when implementing
    interfaces) which C# has fixed (see
    http://www.csharphelp.com/archives/archive171.html for an example of the
    syntax C# uses to address this).

    I don't like the .NET API library, so I hope Sun copies C#'s solution
    into some future version of Java (Java 1.6? 1.7?)

    - Oliver
     
    Oliver Wong, Aug 15, 2005
    #11
  12. Chris Berg

    jan V Guest

    say that Sun, in their infinite wisdom, decide that one
    Of course, and how many, many, dozens (hundreds?) of times has this happened
    in the core library? The Java Bug Database is littered with regression bugs.
    Which is why it's not a great idea to define interfaces containing methods
    that totally overlap with already-existing methods in classes that you will
    then subclass and "impose" said interface on.
     
    jan V, Aug 15, 2005
    #12
  13. Chris Berg

    Daniel Dyer Guest

    I didn't know that C# did things differently in this respect. I'm not
    sure I like it, it would appear that you can change the observed behaviour
    of the object just by casting. It reminds me of multiple inheritance in
    C++.

    In the second example, what happens if I do this:

    t.MyFunction();

    ???

    Does this result in a compile-time error because it's ambiguous or does it
    prefer the I1 version because it is specified first in the extends list?

    Dan.
     
    Daniel Dyer, Aug 15, 2005
    #13
  14. Chris Berg

    jan V Guest

    Well, as I said, it works tecnically, I just wondered if it was
    No, no, **NO** please !!!! Enough of this "Oh, C++ has solved that, let's
    copy C++'s solution into Java".

    Java used to be KISS all the way, and was a huge success because of it. With
    the latest language additions, Java has become decidedly un-Java. Java
    always used to be totally, utterly readable. Now with generics, more and
    more people are writing utterly unreadable code (= garbage, IMO).
     
    jan V, Aug 15, 2005
    #14
  15. Java Interfaces are purely a typing mechanism, which specifies that the
    implementing class (be it a base/abstract/derived class) implements the
    signatures of the interface. It is irrelevant which class within a
    hierarchy satisfies this contract, just that it is satisfied.

    This is because the Interfaces are only concerned with method
    signatures, not their implementation.

    The code you have posted above is very good example of one use of
    interfaces. The MyComponent class is satisfying the Interface contract
    simply because its base class already has a method with the same
    signature.

    This example is not the Adapter pattern though. That pattern would be:


    public abstract class MouseAdapter implements MouseListener {

    public void onMouseDown(MouseEvent e) {
    }

    // rest of interface methods stub implemented
    }

    This pattern is useful if the interface has a lot of methods signatures,
    but the implementing classes do not need to do anything with them. So,
    by having your own class which extends the MouseAdaptor, you don't have
    to stub implement the unneeded methods yourself.

    However, IMHO, this is almost (note I don't say always) an anti-pattern.
    If we used the Interface Segregation Principle, then we would not need
    to have so many interfaceAdaptors.

    HTH

    Andrew
     
    Andrew McDonagh, Aug 15, 2005
    #15
  16. Though as you know, the main benefit of having an interface is the
    typing aspect of it.

    With having MyComponent extend Component, it can only be passed and used
    as an AWT component, which means all of the other methods of Component
    are available too. It also means that users of the MyComponent are now
    dependent upon AWT's component.

    Whereas if it also implements the 'Enableable' interface, we can pass it
    around as Enableable. This gives us the benefit that we have reduced the
    public interface of MyComponent to just those methods we want to. This
    removes dependencies and coupling.

    Without this mechanism, Dependency Inversion, Dependency injection, etc
    would be difficult at best.

    Andrew
     
    Andrew McDonagh, Aug 15, 2005
    #16
  17. Note that I have no problem with the use of the interface. My comment
    about junk code related to my suggestion of a possible, but undesirable,
    way of avoiding the use of an inherited method to satisfy the interface
    requirements.

    Patricia
     
    Patricia Shanahan, Aug 16, 2005
    #17
  18. Sure, but for the OPs sake, I just wanted to expand upon why the
    situation he has is in fact a good thing, if used correctly.
     
    Andrew McDonagh, Aug 16, 2005
    #18
  19. Chris Berg

    Roedy Green Guest

    Not at all. It just means your end object has the behaviours
    described by the interface. How it got them is immaterial.

    The terminology "implements" suggests doing some work. Perhaps if you
    read "implements" as "can act as a".

    In programming, laziness is a virtue.
     
    Roedy Green, Aug 16, 2005
    #19
  20. Chris Berg

    Roedy Green Guest

    the notion of which interface does a method belong to just does not
    come up in Java. A method conforming to two different interfaces
    belongs to both interfaces.

    You can access the method via a class reference or either interface
    reference.
     
    Roedy Green, Aug 16, 2005
    #20
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.