Question

Short answer that I've come to accept:

Firstly, it helps with readability, being able to see which is the superclass apart from interfaces. Secondly, though 'extends' and 'implements' do the same thing of inheriting from a Type and could be expressed in a single keyword, the different words help to express the different idea behind the inheritance. We can see this idea is also expressed in how Interfaces 'extend' other Interfaces rather than 'implement' them.

Thanks for your insight, I think I've learned some good principles from these answers.


Full question:

This is not a question about why Java avoids multiple inheritance. This is also not about the definition of Interfaces and Abstract Classes nor necessarily their conceptual differences, I think most of us understand those principles well enough.

This is just about how these types are inherited

The reason I ask is because sometimes (during the live design phase of projects) I find myself changing an Interface to an Abstract Class, or vice versa, then having to go through all its children to switch between 'extends' and 'implements'. Sure, I could probably plan it out better but this situation just got me thinking if it was all really necessary. If it was a single keyword this would be handled purely by the compiler.

I don't see the need for this distinction between 'extends' and 'implements'; However, I'm not a language designer.. So is there some good reason that I may have overlooked?

I note that Generics actually does throw out this distinction, only using 'extends' for both types. Also, Interfaces can "extend" a list of other Interfaces further blurring the line between 'extends' and 'implements' in my opinion.

Here's an example of what we have vs. what I think I want:

public interface MyInterface extends OtherInterface1, OtherInterface2  {
    public void myInterfaceMethod();
}

public class MySuperclass {
    public void mySuperclassMethod(){ ... }
}

// What we have - If I change MySuperclass to an Interface then this breaks
public class MyClass extends MySuperclass implements MyInterface {
    @Override public void myInterfaceMethod() { ... }
}

// What I want - If I change MySuperclass to an Interface then this is still fine
public class MyClass extends MySuperclass, MyInterface {
    @Override public void myInterfaceMethod() { ... }
}

Thanks

Was it helpful?

Solution

If you need to often switch between interface and class and adapt the code accordingly, there might be a misunderstanding of the different semantics that the syntax only highlights:

  • An interface exposes a contract about how the external world can interact with an object. There is no semantic relationship between different classes that implement the same interface, and in particular, the interface is not a generalization of the class.
    Example: suppose there's an interface Displayable exposes some methods to print or draw an object; the fact that two classes, say Vegetable and MechanicalPart implement it, does not relate semantically these classes. It's just that they can be used in the same way when it comes to display objects. Nobody would come to the idea of cooking a soup with mechanical parts;
    By the way, you may be interested in why an interface is called interface in Java and why Gosling decided to use this distinction (see link).
  • A class defines a type and at the same time exposes its interface. When you extend the class, you create a sub-type that specializes the parent class, for example by providing extended features, or doing things slightly differently. It extends the common structure and behavior.
    Example: When you say class Potato extends Vegetable, you say that there is a very strong semantic relationship between the two and that everywhere where you use a Vegetable object, you could as well use a Potato, because a Potato is a Vegetable. There is a semantically a generalisation/specialisation relationship. Some people have even theoreticised about how this relation should be, and this gave us Liskov Substitution Principle.

Now to answer your question, and abstract class is a class, even if it does not provide the implementation of some methods. In my above example, the fact that Vegetable would be an abstract class and would provide no implementation, does not change the strong nature of its relation with Potato.

Conclusion: from a technical point of view, an abstract class that would only define abstract methods without providing any implementation could look very similar to an interface that also defines some methods that need to be implemented. But both language constructs have different semantics. The difference in syntax only makes explicit this differences in the meanings, in order to force us to think about what we really want to express.

OTHER TIPS

The simplest way to answer this is by observing other languagues. In C#, both extends and implements have been merged into :

public class Foo : IFoo { }

public class Foo : BaseFoo { }

Does it really matter to use a different keyword here? I don't think so. I don't see any benefit to it.

But then again, I was raised with C# and their lack of distinction between extension and implementation. Maybe I'm biased, maybe there genuinely isn't a reason to distinguish between them.


I won't repeat Christophe's answer here, but he's right that the underlying basis for your question is that you often change a base class to an interface (or vice versa), and that's not something that you should be doing, or tailor the language to facilitate more than it already does.

I'm a fan of code that expresses what it means. Having one keyword, and when I read it I have to search for either an interface or a class to know what it means, that is totally impractical. It's almost as bad as having all the names in your address book rot-13 encoded. You can do it, but why?

And of course a future Java version could easily have a language feature that allows you to extend interfaces. So what do you do now?

It is historical founded. Java wanted to improve upon C++. C++ had multiple inheritance, an overriden method could stem from one or more parent classes, having some consequences.

This ambiguity was removed: a Java class is single-inheritance (extends), and can implement several interfaces (implements). This is still a valid design (despite classes and interfaces growing together). Scala for instance has Traits, somewhat like code bearing java interfaces.

Mind also that an interface can extend an other interface. It is remarkable that there extends does not allow several interfaces.

As a class has more functionality than an interface, it is good to mark it separately by extends: constructors especially and fields.

Licensed under: CC-BY-SA with attribution
scroll top