Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to use interfaces or abstract classes? When to use both?

While certain guidelines state that you should use an interface when you want to define a contract for a class where inheritance is not clear (IDomesticated) and inheritance when the class is an extension of another (Cat : Mammal, Snake : Reptile), there are cases when (in my opinion) these guidelines enter a gray area.

For example, say my implementation was Cat : Pet. Pet is an abstract class. Should that be expanded to Cat : Mammal, IDomesticated where Mammal is an abstract class and IDomesticated is an interface? Or am I in conflict with the KISS/YAGNI principles (even though I'm not sure whether there will be a Wolf class in the future, which would not be able to inherit from Pet)?

Moving away from the metaphorical Cats and Pets, let's say I have some classes that represent sources for incoming data. They all need to implement the same base somehow. I could implement some generic code in an abstract Source class and inherit from it. I could also just make an ISource interface (which feels more "right" to me) and re-implement the generic code in each class (which is less intuitive). Finally, I could "have the cake and eat it" by making both the abstract class and the interface. What's best?

These two cases bring up points for using only an abstract class, only an interface and using both an abstract class and an interface. Are these all valid choices, or are there "rules" for when one should be used over another?


I'd like to clarify that by "using both an abstract class and an interface" that includes the case when they essentially represent the same thing (Source and ISource both have the same members), but the class adds generic functionality while the interface specifies the contract.

Also worth noting is that this question is mostly for languages that do not support multiple inheritance (such as .NET and Java).

like image 633
Blixt Avatar asked Aug 05 '09 08:08

Blixt


People also ask

When you should use interface and when use abstract class What are the advantages of one over another?

The short answer: An abstract class allows you to create functionality that subclasses can implement or override. An interface only allows you to define functionality, not implement it. And whereas a class can extend only one abstract class, it can take advantage of multiple interfaces.

In which of these situations are interfaces better than abstract classes?

An interface is better than a abstract class when you want multiple classes to implement that interface and when you don't have to inherit default behavior.

Can you use both abstract classes and interfaces together in the same program?

An interface is mostly considered to be a pure abstract class. However, there is the advantage of using an interface over an abstract class; that is "Multiple Inheritance Support". In C#, two classes (either abstract or concrete) cannot be inherited by the same derived class.

Where do we use abstract class and interface in real life scenario?

A concrete example of an abstract class would be a class called Animal. You see many animals in real life, but there are only kinds of animals. That is, you never look at something purple and furry and say "that is an animal and there is no more specific way of defining it".


1 Answers

As a first rule of thumb, I prefer abstract classes over interfaces, based on the .NET Design Guidelines. The reasoning applies much wider than .NET, but is better explained in the book Framework Design Guidelines.

The main reasoning behind the preference for abstract base classes is versioning, because you can always add a new virtual member to an abstract base class without breaking existing clients. That's not possible with interfaces.

There are scenarios where an interface is still the correct choice (particularly when you don't care about versioning), but being aware of the advantages and disadvantages enables you to make the correct decision.

So as a partial answer before I continue: Having both an interface and a base class only makes sense if you decide to code against an interface in the first place. If you allow an interface, you must code against that interface only, since otherwise you would be violating the Liskov Substitution Principle. In other words, even if you provide a base class that implements the interface, you cannot let your code consume that base class.

If you decide to code against a base class, having an interface makes no sense.

If you decide to code against an interface, having a base class that provides default functionality is optional. It is not necessary, but may speed up things for implementers, so you can provide one as a courtesy.

An example that springs to mind is in ASP.NET MVC. The request pipeline works on IController, but there's a Controller base class that you typically use to implement behavior.

Final answer: If using an abstract base class, use only that. If using an interface, a base class is an optional courtesy to implementers.


Update: I no longer prefer abstract classes over interfaces, and I haven't for a long time; instead, I favour composition over inheritance, using SOLID as a guideline.

(While I could edit the above text directly, it would radically change the nature of the post, and since a few people have found it valuable enough to up-vote it, I'd rather let the original text stand, and instead add this note. The latter part of the post is still meaningful, so it would be a shame to delete it, too.)

like image 150
Mark Seemann Avatar answered Oct 04 '22 11:10

Mark Seemann