there 2 schools of thought on how best extend, enhance, , reuse code in object-oriented system:
inheritance: extend functionality of class creating subclass. override superclass members in subclasses provide new functionality. make methods abstract/virtual force subclasses "fill-in-the-blanks" when superclass wants particular interface agnostic implementation.
aggregation: create new functionality taking other classes , combining them new class. attach common interface new class interoperability other code.
what benefits, costs, , consequences of each? there other alternatives?
i see debate come on regular basis, don't think it's been asked on stack overflow yet (though there related discussion). there's surprising lack of google results it.
it's not matter of best, of when use what.
in 'normal' cases simple question enough find out if need inheritance or aggregation.
- if new class is more or less original class. use inheritance. new class subclass of original class.
- if new class must have original class. use aggregation. new class has original class member.
however, there big gray area. need several other tricks.
- if have used inheritance (or plan use it) use part of interface, or forced override lot of functionality keep correlation logical. have big nasty smell indicates had use aggregation.
- if have used aggregation (or plan use it) find out need copy of functionality. have smell points in direction of inheritance.
to cut short. should use aggregation if part of interface not used or has changed avoid illogical situation. need use inheritance, if need of functionality without major changes. , when in doubt, use aggregation.
an other possibility for, case have class needs part of functionality of original class, split original class in root class , sub class. , let new class inherit root class. should take care this, not create illogical separation.
lets add example. have class 'dog' methods: 'eat', 'walk', 'bark', 'play'.
class dog eat; walk; bark; play; end;
we need class 'cat', needs 'eat', 'walk', 'purr', , 'play'. first try extend dog.
class cat dog purr; end;
looks, alright, wait. cat can bark (cat lovers kill me that). , barking cat violates principles of universe. need override bark method nothing.
class cat dog purr; bark = null; end;
ok, works, smells bad. lets try aggregation:
class cat has dog; eat = dog.eat; walk = dog.walk; play = dog.play; purr; end;
ok, nice. cat not bark anymore, not silent. still has internal dog wants out. lets try solution number three:
class pet eat; walk; play; end; class dog pet bark; end; class cat pet purr; end;
this cleaner. no internal dogs. , cats , dogs @ same level. can introduce other pets extend model. unless fish, or not walk. in case again need refactor. other time.