CodeFarmer
CodeFarmer

Reputation: 2706

Why in this case use Interface over Abstract class?

I was reading a blog post here: http://codeofdoom.com/wordpress/2009/02/12/learn-this-when-to-use-an-abstract-class-and-an-interface/

public interface Actor{
   Performance say(Line l);
}
public interface Director{
   Movie direct(boolean goodmovie);
}
public interface ActorDirector extends Actor, Director{
...
}

It says: In reality, there are Actors who are also Directors. If we are using interfaces rather than abstract classes.We could achieve the same thing using abstract classes. Unfortunately the alternative would require up to 2^n (where n is the number of attributes) possible combinations in order to support all possibilities.

Question: why abstract class is better here ? and why 2^n ?

public abstract class ActorDirector implements Actor,Director{
}

Upvotes: 3

Views: 1134

Answers (4)

supercat
supercat

Reputation: 81307

Inheritance has two parts:

  1. A derived class can regard public or protected methods or fields of its parents as though they are its own.
  2. A derived-type object may be substituted for a base-type object in most contexts where the latter is requested.

A class which implements an interface receives only the latter benefit, but a class which inherits from an abstract class achieves both. On the other hand, with that benefit comes a restriction: because it's only possible for a class to regard one other class's methods and fields as its own, it's only possible for a class to inherit from one abstract class. By contrast, a class can implement (and thus be substitutable for) any number of interfaces.

Don't concern yourself with the combinatorial explosion of abstract classes. Suppose some vehicles can Steer (e.g. CompactCar), others can AttachFollower (e.g. a RailwayLocomotive), and some can do both (e.g. PickupTruck). It should be possible for a PickupTruck to satisfy code needing a vehicle that can Steer, as well as code needing a vehicle that can AttachFollower. If Steer and AttachFollower were both abstract classes, however, there would be no way to declare PickupTruck so one instance could perform both functions. The best one could do would be to define a 'SteerableAndHitchableabstract class which inerits fromSteerableand includes aTrailerHitchmember of typeAttachable`, but that sort of thing is icky even with just two abilities. Adding more abilities in type-safe manner will not only require an exploding number of classes; it will require an expanding number of properties for each class.

Upvotes: 0

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 727047

I think you misunderstood the post: the author is not arguing that an abstract class is better in this situation - on the contrary, he is arguing that an interface is a better fit.

As far as 2^n (or more precisely 2^n-1) goes, the number comes from realization that if you have n orthogonal behavior contracts, you can make 2^n-1 non-empty combinations from them. If you use interfaces to add contracts to classes that implement them, you need only as many interfaces as there are behaviors: the user will be able to make combinations of behaviors that he chooses to implement, up to 2^n-1. If you were to try achieving the same flexibility with abstract classes, you would end up creating not only your desired implementations, but also all the intermediate ones required all the way to a single root, because Java lets you inherit classes only one at a time.

Upvotes: 1

Attila
Attila

Reputation: 28802

You cannot inherit from more than one class (abstract or not), but can implement multiple interfaces

If you were to create abstract classes, you will need one for every combination (n atributes: 2^n possible combination) -- to ensure that each combination can be inherited from, if needed.

If you are using interfaces, you only need to define the n interface (one for each attribute) and implement them as needed.

Upvotes: 6

user177800
user177800

Reputation:

The question you need to answer when deciding on whether you need an Abstract class or not is simple;

Is there any common implementation of any of the methods shared between any of the classes that implement either of these interfaces? If that is yes then you would put that implementation in an AbstractClass.

If that is no then you would just combine the two into a single Interface and have all the implementing classes provide their custom, non-shared implementations.

There is definitely an argument to be made to do both. Have a super-interface that allows for working around single inheritance restrictions, as well as also having an Abstract implementation of that super-interface as well, to provide high-cohesion for any shared default implementations of any of the methods in the interface.

These decisions are easier the more experience you gain solving these problems incorrectly.

Upvotes: 1

Related Questions