Roygbiv
Roygbiv

Reputation: 89

inheritance vs composition - specific case

I have been reading about inheritance vs composition. I know there is already allot about this topic on this site, but i have a question about this specific example I hope will not be seen as duplicate.

Some guidelines I have gathered so far:


So now for the example

I have been working on a simple game engine to practice C++. For this I have made some classes:

There is more of course, but let’s keep it simple for the example.


So - Sprite HAS an image and HAS a position (transform). Following the guideline that would mean composition for both. BUT I think it is just so much easier to have Sprite inherit from Transform.

Because I what to do things sprite->setPosition() and sprite ->setScale().

But It seems to go against convention. What do you all think?

Upvotes: 1

Views: 554

Answers (1)

Jorge Y.
Jorge Y.

Reputation: 1133

When you say "easier" I think you mean "faster", because let's face it, forwarding the calls from the Sprite to the Transform component it's not difficult at all, it just takes more typing (and "less typing" is good, but I would weigh other things first). The problems of choosing inheritance over composition could not be there now, but could arise later.

With public inheritance you just have to declare the inheritance, and all the public interface from Transform is available in Sprite. All. If one day you add a "Rotate" method to the Transform, but don't want Sprites to be shown upside down, then you have to hide the base class method somehow. There are good answers here from Matthieu and CodeFirst about how to do that hiding in C++. But as Matthieu points there, by hiding the method you violate the Liskov Substitution Principle. If you had used composition, you could have just ignored that "Rotate" method in the public interface for Sprite.

With private inheritance you would be a little bit better, because it represents a "is implemented in terms of" relationship between Sprite and Transform, closer to reality than the "is a" relationship represented by public inheritance. But then you would need to put "using" statements to make available the methods from Transform in Sprite (see Eugen answer also in the previous link). So you end up still having to write extra code to achieve your purpose (although less than with composition).

With composition I feel that you have easier options to deal with design problems. Do you want to simply call the component method? You forward the call. Do you want to ban the component method? You don't add it to the Sprite interface. Do you want to add functionality to one method (e.g. keeping the Transform scale from being set to such value that the size of the Sprite Image is too small)? You add the method to the interface but do some extra processing/checkings before/after calling the Transform component...

If you can get your hands on Scott Meyers' Effective C++ book, you have two items that are worth reading for this discussion: "Use private inheritance judiciously" and "Model 'has-a' or 'is-implemented-in-terms-of' through composition". A final point extracted from there in favor of composition: "Both composition and private inheritance mean is-implemented-in-terms-of, but composition is easier to understand, so you should use it whenever you can"

Upvotes: 1

Related Questions