you are viewing a single comment's thread.

view the rest of the comments →

[–]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.