views:

2008

answers:

3

A curious thing happens in Java when you use an abstract class to implement an interface: some of the interface's methods can be completely missing (i.e. neither an abstract declaration or an actual implementation is present), but the compiler does not complain.

For example, given the interface:

public interface IAnything {
  void m1();
  void m2();
  void m3();
}

the following abstract class gets merrily compiled without a warning or an error:

public abstract class AbstractThing implements IAnything {
  public void m1() {}
  public void m3() {}
}

Can you explain why?

+20  A: 

That's because if a class is abstract, then by definition you are required to create subclasses of it to instantiate. The subclasses will be required (by the compiler) to implement any interface methods that the abstract class left out.

Following your example code, try making a subclass of AbstractThing without implementing the m2 method and see what errors the compiler gives you. It will force you to implement this method.

Bill the Lizard
I think the compiler should still throw warnings regarding abstract classes that implement interfaces incompletely, simply because then you need to go looking through 2 class definitions rather than 1 to see what you need in a subclass. This is a language/compiler limitation though.
workmad3
That wouldn't be a good idea, as there can typically be lots of abstract classes and the 'false' warnings would soon overwhelm you, causing you to miss the 'true' warnings.If you think about it, the 'abstract' keyword is there specifically to tell the compiler to supress warnings for that class.
belugabob
@workmad - if you have common implementations for a subset of interface methods it makes better sense to factor it into a separate base class (DRY trumps one-place-code)
Gishu
It would be dangerous to *require* you to put empty method implementations in an abstract class. If you did that then implementers of subclasses would inherit this non-behavior without the compiler telling them there's a problem.
Bill the Lizard
I think what workmad might be suggesting is that you define the methods in the abstract class without a method body and mark them abstract. Doesn't seem like a bad idea to me.
Don
+3  A: 

Perfectly fine.
You can't instantiate abstract classes.. but abstract classes can be used to house common implementations for m1() and m3().
So if m2() implementation is different for each implementation but m1 and m3 are not. You could create different concrete IAnything implementations with just the different m2 implementation and derive from AbstractThing -- honoring the DRY principle. Validating if the interface is completely implemented for an abstract class is futile..

Update: Interestingly, I find that C# enforces this as a compile error. You are forced to copy the method signatures and prefix them with 'abstract public' in the abstract base class in this scenario.. (something new everyday:)

Gishu
A: 

Abstract classes are not required to implement the methods. So even though it implements an interface, the abstract methods of the interface can remain abstract. If you try to implement an interface in a concrete class (i.e. not abstract) and you do not implement the abstract methods the compiler will tell you: Either implement the abstract methods or declare the class as abstract.

Vincent Ramdhanie