Inheritance is the ability for a type to automatically obtain the behaviors of a parent class. Multiple inheritance is the ability for a type to obtain the behaviors of more than one parent class. As a real world example, if Phone was a type, then MobilePhone could be a type that inherits the behavior of the Phone type. This works in many cases, but not in all. What would happen to say a type, CameraPhone that has to have the behaviors of both a Camera and a Phone? One straightforward way to solve this would be to be able to inherit from both. (Note that in this simple example, it is possible to put a camera in a phone or a phone in a camera, but it is not always the case - say a child who inherits the behaviors or features of each of his parents.)
Some object oriented languages used to solve this by denying that multiple inheritance is ever necessary. Others work around the difficulties by providing what is called an interface and the ability for a sub type to subclass one type, but implement many interfaces. Go on the other hand has multiple inheritance. The way to get it is exactly the same way as we did for single inheritance that we already looked at, using anonymous fields. Let’s implement our Camera+Phone=CameraPhone example.
In the above code, there is a
As you might start to notice, the number of paradigms in Go are fairly less, but they have significant extensibility on the design of the rest of the language.
Some object oriented languages used to solve this by denying that multiple inheritance is ever necessary. Others work around the difficulties by providing what is called an interface and the ability for a sub type to subclass one type, but implement many interfaces. Go on the other hand has multiple inheritance. The way to get it is exactly the same way as we did for single inheritance that we already looked at, using anonymous fields. Let’s implement our Camera+Phone=CameraPhone example.
Full code
package main import "fmt" type Camera struct { } func (_ Camera) takePicture() string { //not using the type, so discard it by putting a _ return "Click" } type Phone struct { } func (_ Phone ) call() string { //not using the type, so discard it by putting a _ return "Ring Ring" } // multiple inheritance type CameraPhone struct { Camera //has anonymous camera Phone //has anonymous phone } func main() { cp := new (CameraPhone) //a new camera phone instance fmt.Println("Our new CameraPhone exhibits multiple behaviors ...") fmt.Println("It can take a picture: ", cp.takePicture()) //exhibits behavior of a Camera fmt.Println("It can also make calls: ", cp.call()) //... and also that of a Phone }
Our new CameraPhone exhibits multiple behaviors ...
It can take a picture: Click
It can also make calls: Ring Ring
It can take a picture: Click
It can also make calls: Ring Ring
In the above code, there is a
Camera
type and a Phone
type. By having an anonymous type of each in CameraPhone
, we are able to reach into the behavior of each of them as if they were direct behaviors of CameraPhone
. As you might start to notice, the number of paradigms in Go are fairly less, but they have significant extensibility on the design of the rest of the language.
Hey, loving your turotials man.
ReplyDeleteThanks a lot keep it up. They have helped highlight some links I was missing in my head about the language.
Very usefull
Great tutorial, good help. Thanks.
ReplyDeleteThat's not inheritance ! That's composition !
ReplyDeleteNope, it's inheritance. It could be considered composition if CameraPhone looked only slightly different:
Deletetype CameraPhone struct {
Camera Camera
Phone Phone
}
They appear to behave the same way at first glance but they're different.
"That's not inheritance ! That's composition !"
ReplyDeleteInheritance is intrinsically an OOPs concept, and yes, in that sense given that Go is procedural, this is not 'inheritance'. But as I mentioned in other pages, you get the same result.
I would rather a component based system over a inheritence based system any day. Not bias or anything...
ReplyDeleteSatishVJ:
ReplyDeletethanks< simple and clear example to start out...
about the semantic differences :-0 we can discuss it for years... the point is that I have the flexibility I'm accustomed to (whatever I might want to call it) :-)
for the rest :-) I'm off to write my software and I'll leave theoretical people to talk...
:-)
thanks