I have been asking this question in interviews for some years now. I get to hear a lot of interesting answers from folks. All these answers have he...
For further actions, you may consider blocking this person and/or reporting abuse
Having taken a bit of a break from C# for a while, I think it has changed my perspective. Working in Python has got me thinking more in terms of functional programming. I'd now see this as the following:
My take: An interface is a contract, a class is a concrete representation of something, and an abstract class is a unecessary and limiting combination of the twoβAn additional language construct with a very specific use that can be accomplished naturally other ways.
Abstract classes are the bane of my existence in an inversion-of-control and TDD world.
π "How do you choose between an interface and an abstract class?" You use an interface.
I'd generally recommend interfaces if you want to publish your codebase as library, as your users are not forced to abide your inheritance.
In this scenario, it's advisable to publish an interface and provide a default implememtation (similar to IEnumerable and everything in System.Collections)
Practically, one use I've found for interfaces is to tag classes. The the interface isn't needed by the program, but having it there helps you to understand the purpose of a given class e.g.: "class UIHandler : IClickHandler, IDragHandler"
Nice trick.
Really great article, thanks!
I like that you showed a simple guideline for reasoning about this problem, and I think it works great for lots of cases. However, there are cases where it is not so easy for me to see the distinction.
For instance, I would argue that the interfaces
Map
,List
andSet
from Java represents an "is-a" relationship, and not a "can-do". Other interfaces such asCloneable
andSerializable
are clearly representations of "can-do" relationships (suffix "able").I think interfaces can be used both for "is-a" and "can-do" relationships, while abstract classes can only be used for "is-a" relationships because of the semantics of inheritance.
What if we think along the line of Interfaces for contracts and Abstract classes for partial implementations? Like how the Java API have abstract classes such as
AbstractMap
andAbstractList
for Map and List, respectivelly.I work in the game industry and actually happen to use both interfaces and abstract together. In some cases, abstract base classes can implement interfaces, which makes it pretty handy later not to have to know what such or such class can do. You simply add different "can-do" to different levels of "is-a".
And that makes perfect sense. You have an interface to represent the "can-do" relationship and an abstract class where you can stash any common implementation.
Thank you Suhas, you have just helped me understand the difference btw those concepts. Now I can feel like a pro when asked the tricky question
Speaking of OOP and the basic Shape example, here is a some good lecture from Uncle Bob about why inheritance is bad sometimes (or always)
Bob Martin SOLID
PS: I suggest watching the entire playlist, you will learn a lot. But do not take his teachings as an absolute truth, soak them using your own filters and knowledge and seek for pro/cons in every scenario.
From my experience it's a bad way of thinking replicating real life models into code, above a point. When you have a choice example between an optimization and keeping the hierarchy same as in real life choose the optimization. I think this is the main cause of overusing inheritance.
Also there are tons of materials on why you should prefer composition over inheritance.
I love the way Go implemented interfaces (passive implicit implementations) & classes (not at all). They fixed many problems for big projects & library imports.
Absolutely - composition over inheritance at any time. Having said that, abstract classes have a place in any OO language and I have seen people confusing between abstract classes and interfaces.
Very helpful piece. It's something I always ended up searching for before going one way or another. This is probably the most cogent explanation of the concept that I've read.
Is-a/has-a differenciation is reasonable. However in your Shape example I would use an IDrawable.
U need abstract classes e.g. when the template pattern needs to be implemented.
Cheers
Shape example is just an "example" as it is most commonly understood by everyone. I think it is "Hello World" of inheritance.
Hi Suhas,
Another conceptualization that helped me a lot to understand when and how to use an abstract class is the design pattern "Layer Supertype" by Martin Fowler.
Saludos,