[java] Why an abstract class implementing an interface can miss the declaration/implementation of one of the interface's methods?

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?

This question is related to java interface abstract-class

The answer is


When an Abstract Class Implements an Interface

In the section on Interfaces, it was noted that a class that implements an interface must implement all of the interface's methods. It is possible, however, to define a class that does not implement all of the interface's methods, provided that the class is declared to be abstract. For example,

abstract class X implements Y {   
    // implements all but one method of Y
}

class XX extends X {   
    // implements the remaining method in Y 
} 

In this case, class X must be abstract because it does not fully implement Y, but class XX does, in fact, implement Y.

Reference: http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html


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:)


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.


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.


That's fine. To understand the above, you have to understand the nature of abstract classes first. They are similar to interfaces in that respect. This is what Oracle say about this here.

Abstract classes are similar to interfaces. You cannot instantiate them, and they may contain a mix of methods declared with or without an implementation.

So you have to think about what happens when an interface extends another interface. For example ...

//Filename: Sports.java
public interface Sports
{
   public void setHomeTeam(String name);
   public void setVisitingTeam(String name);
}

//Filename: Football.java
public interface Football extends Sports
{
   public void homeTeamScored(int points);
   public void visitingTeamScored(int points);
   public void endOfQuarter(int quarter);
}

... as you can see, this also compiles perfectly fine. Simply because, just like an abstract class, an interface can NOT be instantiated. So, it is not required to explicitly mention the methods from its "parent". However, ALL the parent method signatures DO implicitly become a part of the extending interface or implementing abstract class. So, once a proper class (one that can be instantiated) extends the above, it WILL be required to ensure that every single abstract method is implemented.

Hope that helps... and Allahu 'alam !


Interface means a class that has no implementation of its method, but with just declaration.
Other hand, abstract class is a class that can have implementation of some method along with some method with just declaration, no implementation.
When we implement an interface to an abstract class, its means that the abstract class inherited all the methods of the interface. As, it is not important to implement all the method in abstract class however it comes to abstract class (by inheritance too), so the abstract class can left some of the method in interface without implementation here. But, when this abstract class will inherited by some concrete class, they must have to implements all those unimplemented method there in abstract class.


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.


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:)


Interface means a class that has no implementation of its method, but with just declaration.
Other hand, abstract class is a class that can have implementation of some method along with some method with just declaration, no implementation.
When we implement an interface to an abstract class, its means that the abstract class inherited all the methods of the interface. As, it is not important to implement all the method in abstract class however it comes to abstract class (by inheritance too), so the abstract class can left some of the method in interface without implementation here. But, when this abstract class will inherited by some concrete class, they must have to implements all those unimplemented method there in abstract class.


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.


Given the interface:

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

This is how Java actually sees it:

public interface IAnything {
  public static final int i;
  public abstract void m1();
  public abstract void m2();
  public abstract void m3();
}

So you can leave some (or all) of these abstract methods unimplemented, just as you would do in the case of abstract classes extending another abstract class.

When you implement an interface, the rule that all interface methods must be implemented in the derived class, applies only to concrete class implementation (i.e., which isn't abstract itself).

If you indeed plan on creating an abstract class out of it, then there is no rule that says you've to implement all the interface methods (note that in such a case it is mandatory to declare the derived class as abstract)


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.


That's fine. To understand the above, you have to understand the nature of abstract classes first. They are similar to interfaces in that respect. This is what Oracle say about this here.

Abstract classes are similar to interfaces. You cannot instantiate them, and they may contain a mix of methods declared with or without an implementation.

So you have to think about what happens when an interface extends another interface. For example ...

//Filename: Sports.java
public interface Sports
{
   public void setHomeTeam(String name);
   public void setVisitingTeam(String name);
}

//Filename: Football.java
public interface Football extends Sports
{
   public void homeTeamScored(int points);
   public void visitingTeamScored(int points);
   public void endOfQuarter(int quarter);
}

... as you can see, this also compiles perfectly fine. Simply because, just like an abstract class, an interface can NOT be instantiated. So, it is not required to explicitly mention the methods from its "parent". However, ALL the parent method signatures DO implicitly become a part of the extending interface or implementing abstract class. So, once a proper class (one that can be instantiated) extends the above, it WILL be required to ensure that every single abstract method is implemented.

Hope that helps... and Allahu 'alam !


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:)


Given the interface:

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

This is how Java actually sees it:

public interface IAnything {
  public static final int i;
  public abstract void m1();
  public abstract void m2();
  public abstract void m3();
}

So you can leave some (or all) of these abstract methods unimplemented, just as you would do in the case of abstract classes extending another abstract class.

When you implement an interface, the rule that all interface methods must be implemented in the derived class, applies only to concrete class implementation (i.e., which isn't abstract itself).

If you indeed plan on creating an abstract class out of it, then there is no rule that says you've to implement all the interface methods (note that in such a case it is mandatory to declare the derived class as abstract)


When an Abstract Class Implements an Interface

In the section on Interfaces, it was noted that a class that implements an interface must implement all of the interface's methods. It is possible, however, to define a class that does not implement all of the interface's methods, provided that the class is declared to be abstract. For example,

abstract class X implements Y {   
    // implements all but one method of Y
}

class XX extends X {   
    // implements the remaining method in Y 
} 

In this case, class X must be abstract because it does not fully implement Y, but class XX does, in fact, implement Y.

Reference: http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html


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.


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:)


Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to interface

Cast object to interface in TypeScript When to use Interface and Model in TypeScript / Angular Is there a way to create interfaces in ES6 / Node 4? Can a normal Class implement multiple interfaces? When to use: Java 8+ interface default method, vs. abstract method How should I have explained the difference between an Interface and an Abstract class? When do I have to use interfaces instead of abstract classes? How to extend a class in python? Interface type check with Typescript Abstract Class vs Interface in C++

Examples related to abstract-class

invalid new-expression of abstract class type Class is not abstract and does not override abstract method When to use: Java 8+ interface default method, vs. abstract method Spring can you autowire inside an abstract class? Abstract Class:-Real Time Example How should I have explained the difference between an Interface and an Abstract class? When do I have to use interfaces instead of abstract classes? Is it possible to make abstract classes in Python? Abstract Class vs Interface in C++ How do you handle a "cannot instantiate abstract class" error in C++?