Reputation: 165
I'm in a bit of a quandary. I have class animal
, let's say it stores basic things like position, etc.. So then I have a class smartAnimal
that extends animal
. Let's say smartAnimal
adds some functionality of being able to make decisions without the user's input.
Now, I have a class dog
that extends animal
. It doesn't extend smartAnimal
because it doesn't need that functionality. So far I'm good: a dog
is an animal
and a smartAnimal
is an animal
. But now I want smartDog
that would extend smartAnimal
but smartDog
should also be a dog
. For example, a lot of the functionality in regular dog
, let's say .sniff()
, .poop()
, and .bark()
should also be in my smartDog
but it won't be unless I literally copy+paste the code, because Java doesn't allow multiple inheritance.
Composition seems inelegant because if I had:
class smartDog{
smartAnimal thisSmartAnimal;
dog thisDog; }
...I'd be duplicating the "stuff" in animal
, like, for example, the position. I would have to deal with two sets of position variables! And duplicates of whatever properties there are in animal
.
Inheriting multiple interfaces doesn't sound like the proper solution either, because let's say dog
was an interface, .sniff()
, .poop()
, and .bark()
's implementation shouldn't have to vary and be re-implemented for smartDog
and whatever other classes.
What's the best practice here? That is, to have both classes dog
and smartDog
?
EDIT:
From some of the comments/answers, let me clarify. In my specific project, a smartAnimal
actually has a whole neural network that controls it. It's a lot of code, and doesn't make sense to abstract it to an interface. The core of the NN functionality is the same no matter what animal has it, but each smartAnimal
subclass would implement the outputs of the AI "brain" differently. Conversely, each animal has it's own functionality that operates the same whether a human controls it or its own AI agent controls it.
Upvotes: 2
Views: 532
Reputation: 4272
Since we are talking about Java here, the model is single-inheritance with multiple interfaces.
That being said, given these examples, the right level of abstraction is appropriate. That is, the answer lies in a combination of:
This is indeed one of the more difficult and important aspects of information modeling and computer science as a whole. Entire groups of books and studies are devoted to this one topic and thus may not be appropriate as a Stack Overflow question, meant to provide straight-forward, simple answers to straight-forward concise questions.
Upvotes: 2
Reputation: 128759
The answer is that this isn't a realistic inheritance hierarchy, which you can tell from the fact that you used the words "adds some functionality" to describe adding methods in a subclass. This isn't proper inheritance. In proper inheritance (in Java, at least) every method should exist at the top level of the inheritance hierarchy. Inheritance is for code reuse, not for adding functionality as you go deeper into the tree. Therefore, there's not really an answer to your question as given.
Upvotes: 3
Reputation: 10833
I think that what you may be looking for there is the new JDK 8 feature called "Default Implementation"
I Think the wise solution without that would be to have the dog inheriting smartAnimal. As such : A smartDog is a dog which is a smartAnimal which is an Animal.
It is difficult to have more precise advice as it really depends of what your objects are implementing. (Do they all have internal state for example ? or are they only defining new behaviours ?)
Upvotes: 2