views:

252

answers:

7

Well I was going to ask what the difference is but it's been answered before. But now I'm asking why did they make these differences? (I'm speaking about java here, I don't know if the same applies to other languages)

The two things seem very similar. Abstract classes can define a method body whilst interfaces can't, but multiple interfaces can be inherited. So why didn't they (by 'they' I mean Sun when they wrote Java) make one thing where you can write a method body and this type can be inherited more than once by a class.

Is there some advantage in not being able to write a method body, or extend multiple times that I'm not seeing?

+2  A: 

Multiple inheritance is more difficult to implement in a language (compiler really) as it can lead to certain issues. These issues have been discussed here before: What is the exact problem with multiple inheritance.

I've always assumed this was a compromise in Java. Interfaces allow a class to fulfill multiple contracts without the headache of multiple inheritance.

Kris
A: 

The other approach you are describing is the approach used by C++ (mixins for example). The issues related to such "multiple inheritance" are quite complex, and has several critics in C++.

Amit Kumar
C++ doesn't have mixins as I understand them. Mixins can be added to a class at runtime ("add Logger behaviour to this DBI instance"), which isn't a core part of the C++ language.
Philip Potter
@Philip I don't know what you mean. Mixins are quite often used in C++, perhaps most well-known in Grady Booch's books.
Amit Kumar
I think we just disagree on the definition of "mixin" then. No big deal, move along.
Philip Potter
@Philip I searched for "runtime mixins" and now I understand what you mean. Dynamic languages are hip, and I seem to be falling behind in that regard.
Amit Kumar
to be honest, my experience of mixins is restricted to Perl's `Moose::Role`s, which aren't quite the same thing either. We have more concepts available than we have words to describe them these days.
Philip Potter
+7  A: 

Because allowing classes to inherit multiple implementations for the same method signature leads to the obvious question, which one should be used at runtime.

Java avoids this by supporting multiple inheritance only for interfaces. The signatures declared in each interface can be combined much more easily (Java basically uses the union of all methods)

Christopher Oezbek
Ah, I knew there must be something I was missing, this makes sense!
Paul
+4  A: 

Multiple inheritance in C++ leads to semantic ambiguities like the diamond inheritance problem. MI is quite powerful, but has complex consequences.

Making interfaces a special case also raises the visibility of the concept as a means of information hiding and reducing program complexity. In C++, defining pure abstract bases is a sign of a mature programmer. In Java, you encounter them at a much earlier stage in the evolution of a programmer.

Pontus Gagge
+1  A: 

Making them one thing is the route that the Scala guys took with Traits which is an interface that can have methods and supports multiple inheritance.

I think interfaces, for me, are clean in that they only specify requirements (design by contract) whereas abstract classes define common behaviour (implementation), so a different tool for a different job? Interfaces probably allow more efficient code generation during compile time as well?

Hannes de Jager
A: 

Inheritance means you inherit the nature (meaning) and responsibility (behaviour) of the parent class, while interface implementation means you fulfill a contract (e.g. Serializable), which may have nothing to do with the core nature or responsibility of the class.

Abstract class let you define a nature that you want to be generic and not directly instanciable, because it must be specialized. You know how to perform some high-level tasks (e.g. make a decision according to some parameters), but you don't know the details for some lower-level actions (e.g. compute some intermediary parameters), because it depends on implementation choices. An alternative for solving this problem is the Strategy design pattern. It is more flexible, allowing run-time strategy switching and Null behaviour, yet it is more complex (and runtime swtiching is not always necessary). Moreover, you might lose some meaning & typing facilities (polymorphism & type-checking becomes a bit harder because the Strategy is a component, not the object itself).

Abstract class = is-a, Strategy = has-a

Edit: as for multiple inheritance, see Pontus Gagge's answer.

streetpc
+1  A: 

Consider this example:

public abstract class Engine
{
  public abstract void switchPowerOn();
  public abstract void sprinkleSomeFuel();
  public abstract void ignite();

  public final void start()
  {
    switchPowerOn();
    sprinkleSomeFuel();
    ignite();
  }
}

Abstract class can help you with having solid base methods which can or cannot be overriden, but in these methods it uses abstract methos to provide you an opportunity to do your specific thing. In my example different engines have different implementations of how they switch power on, sprinkling some fuel for the ignition, and doing the ignition, however the starting sequence of the engine stays always the same.

That pattern is called "Form Template Method" and is quite frankly the only sensible usage of abstract classes in Java for me.

dimitko