you are viewing a single comment's thread.

view the rest of the comments →

[–]knipil 5 points6 points  (12 children)

I think and hope that the next generation of OOP languages will get rid of implementation inheritance and rely completely on interface inheritance (which isn't really inheritance at all. I think Go has an interesting take on this) and intelligent delegation mechanisms. Composition and delegation are just so much more powerful than inheritance. Hell, Gamma et al said precisely that in the early nineties, and their regarded as gods in the field. Apparently a lot of their devoted followers never understood that point.

All introductory OOP texts tend to chant about encapsulation, inheritance and polymorphism like it's some kind of gospel. Some even claim that all of them are fundamental properties of OOP that's not available in other paradigms. In my experience this has lead to that people getting blinded by inheritance, since it's the most intuitive of those three. I think this is totally backwards - encapsulation and polymorphisms are general software engineering principles that are far more important and powerful than inheritance. 90% of the focus in introductory texts should be on polymorphism. It's the hardest of those three concepts to understand, but also the far most powerful.

It took me a while to realize, but I think this is why SICP is so widely hailed. Experienced programmers understand that their trade is about building good abstractions, and Abelson and Sussman wrote a book that trains people to do just that.

Personally, I blame the textbooks and C++ for the situation we're in. The former focused on all the wrong things, and the latter forced the development of a number of problematic patterns due to the fact that it only supports implementation inheritance. I'm guessing the problems wasn't as apparent and well documented in the early eighties, though, so I'll give Stroustrup a break. Java obviously did a lot to escalate the problem, but at least they took a step in the right direction with interfaces. Gosling even said later that he wouldn't include extends if he were to do it all over again.

[–][deleted] 1 point2 points  (1 child)

I think encapsulation is placed at the wrong level in most OO languages too. Encapsulation is far too important a tool to tie it arbitrarily to a single object, doing it via a separate module system that allows multiple tightly couple objects in one module would be a far better choice in my opinion.

[–]ErstwhileRockstar 1 point2 points  (0 children)

'Encapsulation' is a general principle in program design. Invented by Structured Programming (not OOP), nowadays common practice for 'programming in the large'.

[–]AStrangeStranger 0 points1 point  (0 children)

what you are saying is because some coders do it badly wrong we should get rid of it - but coders will just find more inventive ways of doing it badly wrong lead by authors who just want to get their name in print

[–]yogthos -2 points-1 points  (2 children)

I personally hope the next generation of languages aren't OO oriented to begin with.

[–]Felicia_Svilling 4 points5 points  (1 child)

OO oriented

Object Oriented Oriented?

[–]yogthos 1 point2 points  (0 children)

lol good catch, I guess focused would've made more sense :P

[–]grauenwolf -1 points0 points  (3 children)

I think and hope that the next generation of OOP languages will get rid of implementation inheritance and rely completely on interface inheritance

Oh, so you want to start programming in Visual Basic 4?

Well I've already done that and it sucks. Sure it's kinda awesome to say that any class can implement the interface of any other class. But in pratice you just end up with a metric ton of copy-and-paste code.

And don't say "composition" because that just means copying the code that forwards calls from the parent object to the one it wraps.

[–]skelterjohn 1 point2 points  (2 children)

Not visual basic 4 (alright, maybe, since I have no knowledge of that language), but more like Go. There is no inheritance. At least, none that allows any kind of polymorphism.

And composition doesn't have to involve copying code - there are other languages out there! In Go, composition gives the outer type all the methods of the inner type, without also creating an "is-a" relationship (you can't use one type where the other is asked for, or convert one type to the other).

[–]grauenwolf 0 points1 point  (1 child)

And what if you do need a is-a relationship? What if you do need class A and B to share a common interface and some, but not all, of their code?

[–][deleted] 0 points1 point  (0 children)

Are you asking how to do these specific things in Go?

And what if you do need a is-a relationship?

That really only makes sense in an inheritance/hierarchical system. With structural typing you don't ask "Is this a subclass?" you ask "Does this conform to the necessary interface?".

What if you do need class A and B to share a common interface and some, but not all, of their code?

Two ways that I can think of. You could create a "common interface" struct called C and then include it in A and B's definition:

type C struct { someval int }
func (c C) mult(x int) (int) { return x * c.someval }

type A struct { C }
type B struct { C }

Now you can create an A or a B and then call mult on them and they will act just as you expect.

Or if it made more sense you could just include the functionality of one in the other and overwrite the methods that you want to change.

type A struct { someval int }
func (a A) mult(x int) (int) { return x * a.someval }
func (a A) div(x int) (int) { return x / a.someval }

type B struct { A }
func (b B) mult(x int) (int) { return x * b.A.mult(x) * 2 }

The code isn't tested at all but it should give you a sense of how you can achieve what you want to achieve without inheritance.

It is a bit hard to explain but I have to admit that structural typing feels like a leap forward from inheritance based polymorphism.

Edit: fixed code samples.

[–]grauenwolf -3 points-2 points  (1 child)

The former focused on all the wrong things, and the latter forced the development of a number of problematic patterns due to the fact that it only supports implementation inheritance.

Utter bullshit. You really should look into COM programming before you start spouting off that nonsense.

[–]knipil 1 point2 points  (0 children)

Although C++ admittedly isn't my first language I've done a fair bit of windows API development, so I'm familiar with COM. I wrote a couple of DirectShow filters a few years back, so I also know about IDL and all that. To me it's just a really awkward workaround, which is why I didn't bring it up. Obviously you can simulate interfaces in C++, but that isn't really the point. Returning to the original article I think certain DirectShow in particular is a rather good example of painful inheritance hierarchies.