This week's book giveaway is in the OCAJP 8 forum. We're giving away four copies of OCA Java SE 8 Programmer I Study Guide and have Edward Finegan & Robert Liguori on-line! See this thread for details.
One of the choices is The relationship between Cat and Dog is an example of an appropriate use of inheritance. This is of course not correct, however is it only incorrect because of my understanding of the relationship between a cat and a dog and thus the class names don't work properly. I struggled with this thinking it might be a trick question. My cat has four legs and fur so could it be a Dog? (He also spits up an occasional hairball now and then so I would need a method for that as well.) Should class Dog have been renamed to a more appropriate name since Cat could extend all of the properties of Dog?
Originally posted by John Hembree: One of the choices is The relationship between Cat and Dog is an example of an appropriate use of inheritance.
This is a tricky point. Syntatically, this is proper use of inheritence. In fact, there is a definite benefit from using inheritence in this case. Had you not had Cat inherit from Dog, you'd have to redefine the four legs, the fur, and the implementations of the eat and sleep methods within the Cat class. So, in terms of syntax, this is not only a valid use of inheritence, it's a good use of inheritence. However, if we think of this situtation logically, we come to a totally different conclusion. When we say that something inherits from something else, we say that the inheriting object "is a" inherited object. So, in this case, we'd conclude that a cat "is a" dog. Obviously, we know better. If you look at the properties contained by a Dog, there is nothing there that really pertains only to a dog. There are lots of things that have 4 legs, fur, and shed (a cat being one of them). In this case, it might have made more sense to put those attributes into thet pet class and allow Dog and Cat to both extend that class, like this:
This is probably a better use of inheritence because, not only does it make sense syntatically, but it also makes sense logically. A Dog "is a" Pet and a Cat "is a" Pet but a Dog is not a Cat and vice versa. Of course, this is not the only acceptable way to do such a thing. Obviously, not all pets have four legs (what about fish). It is quite possible that you could have a Pet class taht has some great generalizations (like eating and sleeping) and have subclasses of pet that are slightly more specific, like this:
This inheritence hierarchy might even make more sense depending upon your context. In this case, not all pets have four legs and fur, but they all eat and sleep. Hopefully, this helps you out. Corey
hee hee... that's one of the fun things about inheritance...in order to answer the question correctly, you need to know some extra information about the classes There are two key concepts you need to know for the exam: inheritance uses an IS-A relationship aggregation uses a HAS-A relationship so when you ask yourself these questions -- Dog IS-A Cat? -- no Dog IS-A Pet? -- yes Bathroom IS-A Sink? -- no Bathroom HAS-A Sink? -- yes Cat HAS-A Fur? -- yes (not good english... but yes nonetheless) The kind of questions you'll be asked on the exam use obvious concepts like the ones I give above... so don't think too hard about them -- just go with what makes sense and understand the difference between Aggregation and Inheritance and when its right to use which one.
I agree with both that's why I had posted the question. Just wanted to see from those who had gone before me whether anything tricky like this would be on the exam. On Dan's exam I selected that a Cat was a Dog because of the functionality while knowing that the names weren't right.
More thoughts about this example: A) Forget for a moment about the sentence "a cat is a dog". If we inherit is to write code that sends messages to the base type. This code works equally well with objects of derived types (polymorphism). In this case inheritance would be acceptable only if the classes Dog and Cat were not to change in the future. If they do, the program might be interested in modelling a behaviour from the real world that ruins our inheritance relationship. Besides that, the tendency in developing programs is to abandon the preliminar "closed" long lists of requirements, in favor of a short-cycle iterative process in which the classes are modified in a more flexible manner. I mean that the classes Dog and Cat are likely to change during developing. They might change also in maintenance efforts long after the shipment of the program. B) Corey has extracted the comonality of both classes in a pure fabrication class. "FourLeggedFurryPet" was made abstract to indicate that no instance of such class is possible to exist in our program, as it does not exit in the real world the program is supposed to model. What about using an interface instead of such superclass? .If Dog and Cat were not derived from Pet, but they would implement such interface we manage to avoid the inheritance but still there is a common type to write polymorphism calls (the interface). Reasons to avoid inheritance: Bruce Eckel recommends composition against inheritance. Craig Larman says that subclasses are higly coupled to superclasses. Interfaces allow for a kind of multiple inheritance while superclasses do not. C) If no common type is needed composition can be used:
I feel that my post escapes lightly from exam objectives. [ March 13, 2003: Message edited by: Jose Botella ]
SCJP2. Please Indent your code using UBB Code
Joined: Dec 20, 2001
Jose makes some excellent points. One key point that he's really going over is that, while the SCJP exam requires you to know what can be done in Java, it does not really require you to know what should be done when developing software. That's something you learn from experience (or lots of school ). One quick question, Jose - do you have a source for Bruck Eckel's opposition to inheritence in favor of composition? I'd be interested to read his arguments. Don't worry for those of you that are studying for the exams - such subjects aren't "required reading," but these things are nice to know. Thanks, Corey
Joined: Jul 03, 2001
Corey, this is from the appendix B Java Programming Guidelines in Thinking in Java 3rd ed.
Choose composition first when creating new classes from existing classes. You should only used inheritance if it is required by your design. If you use inheritance where composition will work, your designs will become needlessly complicated.
I think that I have read that gurus starting OOP in the early days tend to use inheritance to much, and that the experience adquired with the pass of time showed this to them. This subject is a good question for the OO, Patterns, UML... forum.