Reputation: 65
I've searched in here and other forums and couldn't find a good answer.. I kind of know that Extending classes isn't the best of practices. And that I should use Interfaces more. my problem is that usually I start creating Interfaces and then move to Abstract classes because there's always some functionality that I want implemented on a super class so that I don't have to replicate it in every child classes. For instance, I have a Vehicle class and the Car and Bike child classes. a lot of functionality could be implemented on the Vehicle class, such as Move() and Stop(), so what would be the best practice to keep the architecture clean, avoid code repetition and use Interfaces instead of Inheritance? Thanks a lot!
(if you have no idea why I'm asking this you may read this interesting article: http://www.javaworld.com/javaworld/jw-08-2003/jw-0801-toolbox.html)
Upvotes: 5
Views: 268
Reputation: 81189
Inheritance allows code reuse and substitutability, but restricts polymorphism. Composition allows code reuse but not substitutability. Interfaces allow substitutability but not code reuse.
The decision of whether to use inheritance, composition, or interfaces, boils down to a few simple principles:
Judgment may be required in deciding whether future substitutable classes may have difficulty deriving from a base class. I tend to think approach #5 often offers the best of all worlds, though, when substitutability is required. It's often cheaper than using interfaces alone, and not much more expensive than using inheritance alone. If there is a need for future classes which are substitutable but cannot be derived from the base, it may be necessary to convert the code to use approach #5. Using approach #5 from the get-go would avoid having to refactor the code later. (Of course, if it's never necessary to substitute a class that can't derive from the base, the extra cost--slight as it may be--may end up being unnecessary).
Upvotes: 1
Reputation: 4215
I think, that Interfaces sometime also evil. They could be as avoidance of multiple inheritance.
But if we compare interface with abstract class, then abstract class is always more than interface. Interface is always some aspect of the class -- some viewpoint, and not whole as a class.
So I don't think you should avoid inheritance and use iterfaces everywhere -- there should be balance.
Upvotes: 0
Reputation: 24722
If you keep in mind fundamental difference between interfaces and classes it will make it easier to decide which one to use. The difference is that interfaces represent just a protocol (usually behavioral) between objects involved, while abstract classes represent some unfinished constructions that involve some parts (data). In car example, interface is essentially a blueprint for the generic car. And abstract class would be like prefabricated specific model car body that needs to be filled with remaining parts to get final product. Interfaces don't even have to be in Java - it will not change anything - still blueprint.
Typically you would use abstract class within your specific implementation framework to provide its consumers with some basic functionality. If you just state that you never use abstract class in favor of interface - it's plain wrong from practical standpoint. What if you need 10 implementations of the same interface with 90% of the same code. Replicate code 10 times? Ok, may be you would use abstract class here but put interface on top of it. But why would you do that if you never intend to offer your class hierarchy to external consumers? I am using word external in very wide sense - it can be just different package in your project or remote consumer.
Ultimately, many of those things are preferences and personal experiences, but I disagree with most blanket statements like extends is evil
. I also prefer not to use extra classes (interfaces or abstract) unless it is required by specific parts of the design.
Just my two cents.
Upvotes: 1
Reputation: 4309
Agree with tofutim - in your current example, move and stop on Vehicle is reasonable.
Having read the article - I think it's using powerful language to push a point... remember - inheritance is a tool to help get a job done.
But if we go with the assumption that for whatever reasons you can't / won't use the tool in this case, you can start by breaking it down into small interfaces with helper objects and/or visitors...
For example - Vehicle types include submarine, boat, plane, car and bike. You could break it down into interfaces... IMoveable + Forward() + Backward() + Left() + Right()
IFloatable + Dock()
ISink() + BlowAir()
IFly() + Takeoff() + Land()
And then your classes can aggregate the plethora of interfaces you've just defined.
The problem is though that you may end up duplicating some code in the car / bike class for IMoveable.Left() and IMoveable.Right(). You could factor this into a helper method and aggregate the helper... but if you follow it to its logical conclusion, you would still end up refactoring many things back into base classes.
Inheritance and Aggregation are tools... neither of which are "evil".
Hope that helps.
Upvotes: 0
Reputation: 17357
Inheritance ('extending classes') imposes significant limitations on class design and I'm not sure the use of interfaces as a replacement for inheritance is the best idea since it fails the DRY test.
These days, Composition is favored over Inheritance, so you might consider this post: Prefer composition over inheritance?
Upvotes: 3
Reputation: 6536
Don't believe all you read
Basically, only use the policy of "interfaces only" when you're making a very small tree of classes, otherwise, I promise it will be a pain. Suppose you have a Person "class" (has eat()
and sleep
), and there are two subclasses, Mathematician (has doProblem()
) and Engineer
( buildSomething()
), then go with interfaces. If you need something like a Car class and then 56 bazillion types of cars, then go with inheritance.
IMHO.
Upvotes: 0
Reputation: 2298
Interesting question. Everyone has different approaches. But it all based on personal experience and choice.
Usually, i start with an interface, then let an abstract class inherit that interface. And implement common actions there, and let others to be implemented by who ever inherits this class.
This give few advantageous based on by experience,
1.During function calls you can pass the elements as interface type or abstract class type.
2.Common variables such as ID, Names etc can be put on abstract class.
3.Easy for maintenance. For example, if you want to implement a new interface, then just implement in the abstract quickly.
Upvotes: 2
Reputation: 2364
Do you want an answer for your specific case, or in general? In the case you described, there is nothing wrong with using an Abstract class. It doesn't make sense use an interface when all of the clients would need to implement the exact same code for Move() and Stop().
Upvotes: 0