0

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

17
  • 4
  • 8
    Because interfaces are implemented, and classes are extended. – Robert Harvey Aug 19 '20 at 20:57
  • 4
    Because each one describes a different concept. – Robert Harvey Aug 19 '20 at 21:10
  • 3
    You're right that different keywords aren't inherently necessary. But sometimes non-necessary features are desirable to language designers. Similarly, you don't really need semicolons, and you don't really have to reserve keywords. But Java's language designers thought that all of these unnecessary features are good for their language. Here, part of the reason might be that class inheritance and interface inheritance usually mean different things, but are definitely implemented completely differently under the hood. – amon Aug 19 '20 at 22:36
  • 2
    Because implementation and extension is fundamentally different in the Java language. They are very much separate, even in the final classfile there is a section for parent class and a section for all implementing interfaces. Plus, it shows you syntactically which is a class extension and which is an interface extension - as the difference is important – Carson Graham Aug 20 '20 at 14:21
6

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.

7
  • 2
    It might be worth adding that it's not uncommon to have both an interface and an abstract class at roughly the same level of abstraction: the interface represents the contract that all implementations must have, the abstract class the base that most implementations are related to. This is generally a better idea than changing one into the other as the OP says they are currently doing. – IMSoP Aug 21 '20 at 9:17
  • 1
    One could argue that "an abstract class that would only define abstract methods without providing any implementation" is one of the reasons to use interfaces, i.e. as a way to enforce that no implementation is provided. (C# recently broke that idea by allowing interfaces to provide default implementations, which I'm not fond of) – Flater Aug 21 '20 at 9:57
  • 1
    @Flater interesting remark! If one has a hammer in the hand,every problem looks like a nail. In C++ there are only classes and you’d use an abstract class to get a reusable interface. But languages that do make the distinction allow to express the sometimes subtle difference between opportunistic code reuse (default implementation of an interface) and true semantic relationship (and common behavior). – Christophe Aug 21 '20 at 10:47
  • 1
    I definitely do know the differences between classes and interfaces, however, in the context of inheritance they were basically just Types in my eyes. Though, I'm starting to see the light with this answer.. even though extends and implements do the exact-ish same thing of just inheriting from some Type, the different words force a more clear expression of the new Type you are defining. – xtratic Aug 21 '20 at 18:54
  • 1
    @Flater Java has had default method implementations in interfaces since 1.8 which has been out for quite a few years. It was a necessary step to allow new methods on interfaces without breaking backwards compatibility. While they create a potential for abuse, they can be nice. For example, the default implementation for Iterator.remove() is now an UnsupportedOperationException which is almost always what I want when implementing an Iterator. – JimmyJames Aug 21 '20 at 19:52
3

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.

4
  • Indeed, in my answer I focused more on the reason to have distinction between the class and the interface rather than on the syntactic way to express their use. Coming from a C++ background I like the simple “:” although I have to admit that the keywords express better what is behind, and at the time Java was designed, IDE’s were not so powerful to remind the definition of an identifier in a hoovering tooltip, that maybe make the necessity to distinguish less obvious. – Christophe Aug 21 '20 at 10:56
  • This was pretty much what I was thinking, and I was going along with my philosophy that we shouldn't really care whether a Type is an Interface or Class when we're referencing it, such as with List<MyThing> myThingList;.. All that matters is that they're Types which define the role we need. I was thinking this philosophy might've applied when declaring inheritance but, even though both words just define inheritance from a Type, it may be beneficial that extends and implements express different intent behind the inheritance. – xtratic Aug 21 '20 at 19:02
  • @xtratic: We should care about the difference, but that is precisely while most naming conventions have you prepend I to interface names. Rather than only seeing it in the implementing class' definition, you can see it everywhere. – Flater Aug 21 '20 at 20:40
  • @Flater I understand it's the convention of C# but I disagree with the I prefix for Interfaces. Also, many Java libraries I use go the other way by suffixing Impl for implementations; I'm not sure I agree with this either but at least it emphasizes interfaces as the types you should be using more often. I prefer simply using natural names that describe the interface or class, interfaces often having a more general name e.g. the List interface and ArrayList implementation. – xtratic Sep 3 '20 at 18:47
1

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?

1
  • 2
    Interfaces in java already can extend other interfaces. (Though they cannot implement them.) – mtj Aug 21 '20 at 10:33
1

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.

1
  • Yeah, that case of interface MyInterface extends OtherInterface1, OtherInterface2 {...} was another of my main issues with extends being a fuzzy word. – xtratic Aug 21 '20 at 18:23

Not the answer you're looking for? Browse other questions tagged or ask your own question.