Live data from Hacker News

Inheritance Often Doesn't Make Sense

sicpers.info

201–210 of 255 posts

Re: Inheritance Often Doesn't Make Sense

#201

I took over the maintenance and enhancement of a customer's eCommerce site. It's written in Python, using an ancient framework - Pylons. The person who originally designed and wrote it, coded large super classes and then subclassed off those. And then somtimes subclassed off those subclasses. So now I'm lost in a maze of twisty classes/subclasses, which makes maintaining and enhancing this eCommerce site much, much m…

> you can use Inheritance in many, many ways which can make life very difficult - nay, miserable - for your future self and especially for anyone 'inheriting' your project.

The principle of “Composition Over Inheritance” is really helpful. You should google it if you’re not familiar! It’s often a better alternative than deep inheritance hierarchies.

Re: Inheritance Often Doesn't Make Sense

#202
post #191

Earlier quoted context omitted.

No. Even less so with the pastry dough squashed into new dimensions. Or when a citizen turns into a soldier -- an army camp is like a soldier factory/constructor. Hmm, how's that for a mixed metaphor?

I disagree. If you remold a square piece of pastry dough into a circle you haven't "circled the square", you have destroyed the square entirely! I don't quite get the army metaphor, but I don't think the relationship of "citizen" and "soldier" is analogous to that of "rectangle" and "square" or even "rectangle" and "rectangle with different dimensions".

>I disagree. If you remold a square piece of pastry dough into a circle you haven't "circled the square", you have destroyed the square entirely!

Well, the physical thing is all still there, just in a different shape.

You have destroyed only an abstract quality, it's squareness, not the thing.

So you haven't "destroyed it" entirely anymore than changing the width of an object to something equal or different than it's height its 'destroying" the object. It just sets a value for a field of the same struct in memory.

Whereas your argument was "A rectangle has a width and height, and you can't just will it to have a different width and height and expect it to obey you through some force of nature".

If by the rectangle you mean the abstract quality, then you're right, you can't.

But we're talking about an object in computer memory that's an instance of a square or a rectangle, or about some physical thing that is one or the other shape.

And if you mean those, then yes, you can very much will that object to a different width and height.

Which is the one of the distinctions TFA makes: the abstract quality can't change, but the thing that embodies that quality can change qualities (and, with them, attributes, like width and height).

Re: Inheritance Often Doesn't Make Sense

#203

Earlier quoted context omitted.

What you are describing is an interface, not inheritance. They are implementing an pulley interface, not inheriting a specific pulley implementation from a common housing or something.

The distinction between "implementing" an interface and "inheriting" a base class is largely just a Java-ism. To some extent, it's a distinction without a difference - at a semantic level, Java only distinguishes between interfaces and purely abstract base classes because one allows multiple inheritance and the other doesn't, and the separate "inherits" and "implements" keywords flow from there. Other languages (like…

I kind of like interfaces as they are basically less powerful traits. I think there is a big difference to class inheritance and the difference between e.g. Jave and C# is just syntactic.

When you implement interfaces you have to explicitly implement all methods. If you implement them correctly all methods using them continue to stay correct (including C# extension methods or java interface default methods).

With class inheritance you have two large problems: you also inherit state that you might not need, might not have access too and might change in future versions of your base class.

Secondly you might need to override methods of the base class to provide correctness. If your base class adds/changes methods your subclass can easily behave wrongly.

Re: Inheritance Often Doesn't Make Sense

#204

If you ever open the hood of a modern car and look around a bit you'll discover that at the front there's a half dozen pullies connected to one or more belts. Each of these pullies is connected to some diffeerent system each able to turn rotational acceleration into a useful service. The alternator converts that rotational energy into electricity. The AC unit uses it to operate a heat pump. The coolant and oil pumps…

You’ve described interfaces, not so much inheritance.

Can you give a mechanical example of inheritance, so we can see the difference?

Re: Inheritance Often Doesn't Make Sense

#205

Earlier quoted context omitted.

What you are describing is an interface, not inheritance. They are implementing an pulley interface, not inheriting a specific pulley implementation from a common housing or something.

The distinction between "implementing" an interface and "inheriting" a base class is largely just a Java-ism. To some extent, it's a distinction without a difference - at a semantic level, Java only distinguishes between interfaces and purely abstract base classes because one allows multiple inheritance and the other doesn't, and the separate "inherits" and "implements" keywords flow from there. Other languages (like…

>it's a distinction without a difference

Never looked at it that way. With inheritance, you're essentially re-using behavior that treats like things with like properties in a similar way. With interfaces, you are providing unique, black-boxed behavior that conforms to an operational specification.

Interfaces are also more externalized. They are intended for consumption from outside of any particular class hierarchy, and don't necessarily represent like things nor operate on the internal properties of a particular class or hierarchy.

OTOH, consider the use of inheritance wherein a major operation or algo is implemented and exposed via a public method on an abstract base class, but one or more type-specific abstract methods on which the algo depends is implemented by subclasses in a type-specific way. This more "inverted" structure probably better highlights a distinction with a real difference. Your subclasses are inheriting major behaviors and "tweaking" the behavior as needed.

You could probably pull this off with interfaces, but it's more convoluted. You'd have one class with several external classes that implement some interface and have reduced access to properties of the original class. So, you may now have to expose properties that you'd otherwise prefer not to. And, you have to manage instantiation of the appropriate interface-implementing classes.

>it's entirely possible to "inherit" a base class without inheriting a single bit of information

Sure, you can override every method in a base class, essentially rendering it not inheritance. But, you could also not extend anything at all and opt not to use interfaces or any other OO-construct. It comes down to design.

Re: Inheritance Often Doesn't Make Sense

#206

Earlier quoted context omitted.

You’ve described interfaces, not so much inheritance.

Can you give a mechanical example of inheritance, so we can see the difference?

I think the term “interface” is used in many related but different ways in software, but I think the most obvious mechanical analogy would be basically anything that uses a common “plug” or “adapter.” Like a vacuum cleaner with different attachments. Or even HDMI for video/audio.

Re: Inheritance Often Doesn't Make Sense

#207
post #21

Earlier quoted context omitted.

I always find that the common example of Rectangles and Squares leads me to a different conclusion. It assume that the best way to go about is to only have a single sideLength method, but from a data structure perspective it seems more obvious that the Squares class substitute instead the validation method by adding constraints that a valid square only exist when both sides are equal. Rectangle class must already hav…

But then both are just a kind of polygon, with an arbitrary number of sides of arbitrary length. At which point you really want a variable length list of Sides, each with a length property. Or you want a series of points with relative coordinates, making the sides implicit. Or or or... What I take from it is that there is no one true object model, there is no universally "correct" way of solving the problem. An evolv…

It's interesting because it highlights that if a thing has so many properties describing what it is, then at a certain point it's not a thing at all, but a collection of characteristics that could be tweaked to describe anything.

At that point, the idea of behaviors is rendered void, as the universe of possible behaviors is just too large.

So, I think that's the guiding principle in your suggestion to consider what value a given design provides to the system: that is, start by modelling the behaviors your system requires, then create an object hiearchy that reflects those behaviors most concisely.

This is probably our intent, but we may be derailed by too little respect for YAGNI.

Re: Inheritance Often Doesn't Make Sense

#208
post #191

Earlier quoted context omitted.

I disagree. If you remold a square piece of pastry dough into a circle you haven't "circled the square", you have destroyed the square entirely! I don't quite get the army metaphor, but I don't think the relationship of "citizen" and "soldier" is analogous to that of "rectangle" and "square" or even "rectangle" and "rectangle with different dimensions".

> I disagree. If you remold a square piece of pastry dough into a circle you haven't "circled the square", you have destroyed the square entirely! Well, the physical thing is all still there, just in a different shape. You have destroyed only an abstract quality, it's squareness, not the thing. So you haven't "destroyed it" entirely anymore than changing the width of an object to something equal or different than it'…

> You have destroyed only an abstract quality, it's squareness, not the thing.

Here we are in agreement.

> But we're talking about an object in computer memory that's an instance of a square or a rectangle, or about some physical thing that is one or the other shape.

Everything in a computer program is an abstraction, and of course you can arrange these abstractions however you like. You could create an instance of a Square that inherits from Paper and has dimensions of "A8". I'm merely arguing that when building an object whose shape may change, using a PastryDough class is probably preferable to using one called Square.

Re: Inheritance Often Doesn't Make Sense

#209

Earlier quoted context omitted.

You’ve described interfaces, not so much inheritance.

In the language of the article, this is subtyping without subclassing. Sure Java/C# implement this as interfaces, but in C++ this would be a case of multiple inheritance. This is a good example of the article's main point that people mean a lot of different things by inheritance and get different value from the different applications of the concept.

There are at least a few ways to define and implement interfaces in C++ without touching inheritance.

Re: Inheritance Often Doesn't Make Sense

#210
post #61
post #15

> A common counterexample to OO inheritance is the relationship between a square and a rectangle. Geometrically, a square is a specialisation of a rectangle: every square is a rectangle, not every rectangle is a square. Alternatively, you can argue that a rectangle is just a square with the additional freedom to vary the width and height independently. So in C++ syntax you would have: class Square { protected: size_t…

Well, the conceptual view is always first. So in fact a square is a subclass of a rectangle. Implementation comes second, and has to find out how much code sharing is possible.

I prefer the data representation comes first, especially in a language like C++.

Maybe you can represent 1000 squares with 1000 integers. If you need polymorphism on top of that, there are plenty of approaches without rearranging or copying the data to make it fit a type taxonomy.

Post reply on HN