This week's book giveaway is in the OO, Patterns, UML and Refactoring forum. We're giving away four copies of Refactoring for Software Design Smells: Managing Technical Debt and have Girish Suryanarayana, Ganesh Samarthyam & Tushar Sharma on-line! See this thread for details.
Looks good. The only change I might suggest would be to eliminate the abstract Shape class and just have Triangle, Circle, and Rectangle implement the Shape interface directly. The advantage of this is that if you start coding for these objects in a complex application, you may find that it would make more sense to make these objects part of some other class hierarchy.
Since Java does not allow multiple inheritance, don't "waste" your one shot at having a class inherit from another class. By implementing the interface only, your objects are free to inherit from another class that might be more appropriate and provide more benefits for code reuse. The rule of thumb provided by Joshua Bloch in his book Effective Java is "Prefer interfaces to abstract classes".
I see your point, but what about the 'name' variable, I would have to declare this field in the 3 subclasses wouldn't I?
My code makes use of code reuse, what do you think?
Joined: Feb 15, 2005
Yes, having an abstract class does save you from having to code a name variable and getter/setter in each class. That's a point in favor of an abstract class. The trade-off, though, is that the class becomes less flexible. You stated at the beginning of your first post that the assignment was to have each class calculate the area. The interface accomplishes that beautifully without an abstract class. The name attribute was something you added as an afterthought, and is peripheral to the real point of the class. I'd say it's not worth making the class less flexible.
This is obviously a simple application, so it doesn't really matter, but in the real world, it's a good idea to keep classes free of dependencies on a static hierarchy whenever possible.
Here's an example of what I'm talking about: Suppose now you want to draw each of these shapes on a screen. You now have a whole lot of other things to take into consideration, such as coordinates, background color, translucence, etc. Since all you used was a interface to calculate the area, you're free to have these classes implement as many other interfaces as you want (e.g. drawable, expandable, movable, etc.). Now suppose you have a whole lot of default behavior you want each of these shapes to inherit that has nothing to do with area, and it would be really convenient just to have the shape classes inherit from a class that embodies all that default behavior. If the shape classes already inherit from an abstract class, you're just out of luck, because a Java class can only inherit from one superclass. I think you can see why you don't want to play the abstract class card until you really need it.
You just have to weigh the benefits on either side and make your decision. If, for example, there were ten properties shared by all classes, that would probably swing my decision over to using an abstract class. With only one property, though, I think I'd prefer to keep the class more flexible and just do the extra work of coding the property in each class.