Live data from Hacker News

Why composition is often better than inheritance

joostdevblog.blogspot.com

71–80 of 97 posts

Re: Why composition is often better than inheritance

#71
post #56

In Python, we use mixins. Mixins can only inherit from 'object' and nothing else, like this: class PhysicsobjectMixin(object): def update_physics(self): pass def apply_konckback(self, force): pass def get_position(self): pass class FightMixin(object): def attack(self): pass def defend(self): pass class TalkMixin(object): def say_something(self): pass class Character(PhysicsobjectMixin, FightMixin, TalkMixin): pass cl…

I don't know if you've ever used Django, but the entire thing is based on inheritance. When they introduced Class Based Views it got so complex that someone had to make this site just for exploring the inheritance tree: http://ccbv.co.uk

There is a good discussion about it here: http://lukeplant.me.uk/blog/posts/djangos-cbvs-were-a-mistak...

Re: Why composition is often better than inheritance

#72
post #62

Meh. I think this phrase has been repeated until it has lost any connection with the original intent and turned into a generic "INHERITANCE BAD! COMPOSITION GOOD!" without much meaning attached to either word. I haven't found the original source, but I've always presumed the statement originally referred to some of the bizarro "inheritance-as-composition" stuff in the early C++ days: for instance, you might have a cl…

You can only inherit from one class in ruby. You can mixin multiple modules into a class. So they aren't entirely equivalent.

Under the hood, mixing in modules actually is inheritance. An anonymous class is created that has all the module's methods, and this class is added to the inheritance hierarchy.

They are quite literally identical, even if Ruby tries it's best to hide that fact.

Re: Why composition is often better than inheritance

#73
post #17
post #6

Earlier quoted context omitted.

Do you have examples? Most modern Java libraries I know (e.g. Guava) implement interfaces and heavily use composition. The "inheritance based" things mostly got deprecated/replaced when Java 1.5 introduced generics and most libraries needed to be heavily changed anyways.

The Android View subclasses are an interesting example of a deep inheritance hierarchy in a relatively modern design.

The Android API is fascinatingly anachronistic. I have been programming Java since 1.0.2, but only recently started working with Android. It's been like stepping through a portal back to a time when we had no idea how to structure software.

Re: Why composition is often better than inheritance

#74

While it's possible to overuse inheritance, I don't think replacing it with composition is all that much better, and in addition all those forwarding methods that do nothing more than call another (could they even be optimised out?) are a great example of code that would need to be written, consuming resources like programmer time, but otherwise serves no true useful purpose to the functionality of the software. The…

> The complexity only changes form, so instead of tracing the flow through an inheritance hierarchy you're just doing it through chains of forwarding methods. It's for this same reason I don't believe so much his argument for readability and short classes - breaking everything up does not make things simpler, it makes the complexity spread out over a larger area; while it may be true that it is easier to understand an individual piece, it becomes more difficult to understand the system as a whole.

Preach it! Whilst immense monolithic classes are bad, smashing a system up into a million tiny bits is just as much of a barrier to understanding. It is baffling to me that this is not immediately obvious to everyone.

See also the microservices movement!

Re: Why composition is often better than inheritance

#75
post #69

Earlier quoted context omitted.

> While it's a well-written article, it really seems like beating a dead horse I graduated college about 10 years ago, and I was never taught anything near composition over inheritance. I was told about inheritance, but had to learn from other coworkers and experience that composition is much favored over inheritance. Now I mentor a number of junior developers and they need to be told composition over inheritance oft…

"I was told about inheritance, but had to learn from other coworkers and experience that composition is much favored over inheritance." You weren't taught that, because it isn't true. Inheritance is appropriate sometimes, composition at other times. In particular, when a two objects are modeled by an ISA relationship, you should use inheritance. When they're modeled by HASA, you should use composition. A Dog is not a…

You're missing the most important cases - there are cases where it could go both ways in terms of ISA vs. HASA, in which case (the article says) you should use HASA.

Just saying "use the tool appropriate to the job" dismisses the entire problem where in the real world, it isn't clear what that is.

Re: Why composition is often better than inheritance

#76
Consider how these things get stored. In the inheritance model, you might have a big quad tree or some other data structure of PhysicsObjects, and just run through and call updatePhysics() on all of them.

In the composition model, we now have multiple classes (Character, Pickup, Projectile), each with an unrelated updatePhysics(). This means code duplication to call the relevant method on each separate class.

We could relate them all via an interface, instead of inheritance; now we can store IEntity or whatever. We will soon discover three needs that are awkward to address:

1. Whenever we want to add some new method (say `fall`), we must go back and implement it separately in each class.

2. Different classes will want to share implementations. For example, both Characters and Pickups bounce on fall.

3. Some classes will want to specialize an implementation to do more. Characters bounce on fall, but also take damage.

In practice you may end up with both: an interface that your engine talks to, but also a common base class that provides sane defaults.

So while interfaces allow uniform interactions with disparate classes, inheritance provides that and also the ability to share and specialize the implementations. So inheritance solves some problems that interfaces cannot.

See also default methods in Java, which makes an interface more like a class, and implementing an interface more like inheritance. The documentation even says that a class that implements an interface inherits its default methods.

Re: Why composition is often better than inheritance

#77
post #69

Earlier quoted context omitted.

> While it's a well-written article, it really seems like beating a dead horse I graduated college about 10 years ago, and I was never taught anything near composition over inheritance. I was told about inheritance, but had to learn from other coworkers and experience that composition is much favored over inheritance. Now I mentor a number of junior developers and they need to be told composition over inheritance oft…

"I was told about inheritance, but had to learn from other coworkers and experience that composition is much favored over inheritance." You weren't taught that, because it isn't true. Inheritance is appropriate sometimes, composition at other times. In particular, when a two objects are modeled by an ISA relationship, you should use inheritance. When they're modeled by HASA, you should use composition. A Dog is not a…

I don't see how this isn't circular. The principle is about the choice of how to model things.

Re: Why composition is often better than inheritance

#78
post #2

While it's a well-written article, it really seems like beating a dead horse. Composition over inheritance is a basic rule of OO programming, so much so that it has its own wikipedia page ( http://en.wikipedia.org/wiki/Composition_over_inheritance )

> While it's a well-written article, it really seems like beating a dead horse I graduated college about 10 years ago, and I was never taught anything near composition over inheritance. I was told about inheritance, but had to learn from other coworkers and experience that composition is much favored over inheritance. Now I mentor a number of junior developers and they need to be told composition over inheritance oft…

>It seems more natural and intuitive to inherit than compose

Especially when you finally figure out inheritance and OO you fall in to that "when all you have is a hammer".

Composition is not an obvious way to approach this problem when you've been taught to solve problems with inheritance - and it fits "so nicely".

Re: Why composition is often better than inheritance

#79
post #44

Earlier quoted context omitted.

There have been many implementations of mixins, and many that I'm aware of, like Scala, are inheritance based. The nice thing about mixin style inheritance is that inheritance becomes much more composable. The type of an object then is not its class, but the set of mixins it extends.

Scala's implementation is definitely an interesting and a valuable one. I'm not debating that inheritance-based mixins are useful, they definitely are. It's just that they aren't necessarily inheritance-based, and there are many implementations of mixins that aren't, so defining it as such is at best somewhat limited and at worst misleading. On a side note: scala's implementation, internally, is composition-based, si…

The type enhancement means that traits could replace classes completely in scala, which is kind of exciting. The problem with traits is that state must be inlined even if implementations are not (so they are a mixture of mixins and small talk style traits). I'm well versed in how they are implemented in scalac.

What non-CL mixins are not inheritance based? Python?

Re: Why composition is often better than inheritance

#80

In Python, we use mixins. Mixins can only inherit from 'object' and nothing else, like this: class PhysicsobjectMixin(object): def update_physics(self): pass def apply_konckback(self, force): pass def get_position(self): pass class FightMixin(object): def attack(self): pass def defend(self): pass class TalkMixin(object): def say_something(self): pass class Character(PhysicsobjectMixin, FightMixin, TalkMixin): pass cl…

[deleted]
Post reply on HN