Inheritance and subclassing in Go - or its near likeness
原文: http://golangtutorials.blogspot.com/2011/06/inheritance-and-subclassing-in-go-or.html
---------------------------------------------------------------------------------------------
Those of you used to other object oriented languages probably already know what inheritance and subclassing is. In simple terms, it is the ability of one type to inherit the behavior of another type. An Employee has all the behaviors of a Human, and then some more. A Ferrari has all the behaviors of a Car, and some more. An Aston Martin has all the behaviors of a Car, and then some more, but not the same as that of a Ferrari. So if we could generalize a Car and define behaviors for it, then both a Ferrari and an Aston Martin could reuse it, instead of each redoing it from scratch. Basically, it inherits the behavior of a more generalized type or class. Or in the language of object oriented programming, there could be a class and a subclass of it, where the subclass appears to inherit all the behaviors of the parent class. The subclass could go on to define more specialized behaviors for itself.
Now what does this mean for us in programming? Assume you had the class Car
and it has a member method called numberOfWheels()
. If we create a subclass Ferrari
of Car
, what it means in coding is that we should automatically have a Ferrari.numberOfWheels()
- i.e. the subclass gets the super class’ behaviors or its methods.
With what we’ve learnt already with Anonymous fields in structs and Methods on structs, we can achieve the same paradigm in Go. If, like me, you have been more used to object oriented programming so far, a couple of examples will help explain how.
Full code
package main import "fmt" type Car struct {
wheelCount int
} // define a behavior for Car
func (car Car) numberOfWheels() int {
return car.wheelCount
} type Ferrari struct {
Car //anonymous field Car
} func main() {
f := Ferrari{Car{4}}
fmt.Println("A Ferrari has this many wheels: ", f.numberOfWheels()) //no method defined for Ferrari, but we have the same behavior as Car.
}
In the above program, we have only defined a method or behavior for Car
. Since we then defined Car
as an anonymous field in Ferrari
, the latter class automatically can call on all the visible behaviors/methods of the anonymous field type. So here, we have not subclassed a parent class, but composed it. But the effect is the very same - you have all the behaviors of the parent with none of the frills of object oriented programming. C’mon, you have to agree with me that that is cool! Let’s bring in the Aston Martin also now, and this time add some individual behavior in addition to that inherited.
Full code
package main import "fmt" type Car struct {
wheelCount int
} func (car Car) numberOfWheels() int {
return car.wheelCount
} type Ferrari struct {
Car
} // a behavior only available for the Ferrari
func (f Ferrari) sayHiToSchumacher() {
fmt.Println("Hi Schumacher!")
} type AstonMartin struct {
Car
} // a behavior only available for the AstonMartin
func (a AstonMartin) sayHiToBond() {
fmt.Println("Hi Bond, James Bond!")
} func main() {
f := Ferrari{Car{4}}
fmt.Println("A Ferrari has this many wheels: ", f.numberOfWheels()) //has car behavior
f.sayHiToSchumacher() //has Ferrari behavior a := AstonMartin{Car{4}}
fmt.Println("An Aston Martin has this many wheels: ", a.numberOfWheels()) //has car behavior
a.sayHiToBond() //has AstonMartin behavior
}
Hi Schumacher!
An Aston Martin has this many wheels: 4
Hi Bond, James Bond!
In the above program, both the Aston Martin and the Ferrari, behave like a car - since both can access the numOfWheels
method from Car
as if it was directly available in it. In addition, it defines its own behaviors that only itself can use. So the neither the Car
nor the AstonMartin
can call sayHiToSchumacher
; similarly only the AstonMartin
can call sayHiToBond
and neither Ferrari
nor Car
can do that.
In short, by using Go’s concept of anonymous fields, we arrive at the same concept as subclassing and inheritance. It would appear inside out at first that to subtype something, you put the parent type within the sub type.
Inheritance and subclassing in Go - or its near likeness的更多相关文章
- Less is exponentially more
Less is exponentially more (原文出处:rob pike 博客,https://commandcenter.blogspot.jp/2012/06/less-is-expo ...
- Go is more about software engineering than programming language research.
https://talks.golang.org/2012/splash.article Go at Google: Language Design in the Service of Softwar ...
- Effective Java 17 Design and document for inheritance or else prohibit it
Principles The class must document its self-use of overridable methods. A class may have to provide ...
- 代码的坏味道(12)——平行继承体系(Parallel Inheritance Hierarchies)
坏味道--平行继承体系(Parallel Inheritance Hierarchies) 平行继承体系(Parallel Inheritance Hierarchies) 其实是 霰弹式修改(Sho ...
- 5.Inheritance Strategy(继承策略)【EFcode-first系列】
我们已经在code-first 约定一文中,已经知道了Code-First为每一个具体的类,创建数据表. 但是你可以自己利用继承设计领域类,面向对象的技术包含“has a”和“is a”的关系即,有什 ...
- single-table inheritance 单表继承
type 字段在 Rails 中默认使用来做 STI(single-table inheritance),当 type 作为普通字段来使用时,可以把SIT的列设置成别的列名(比如不存在的某个列). 文 ...
- C++: virtual inheritance and Cross Delegation
Link1: Give an example Note: I think the Storable::Write method should also be pure virtual. http:// ...
- React之Composition Vs inheritance 组合Vs继承
React的组合 composition: props有个特殊属性,children,组件可以通过props.children拿到所有包含在内的子元素, 当组件内有子元素时,组件属性上的child ...
- What is the difference between the ways to implement inheritance in javascript.
see also : http://www.w3school.com.cn/js/pro_js_inheritance_implementing.asp http://davidshariff.com ...
随机推荐
- 【GStreamer开发】GStreamer播放教程05——色彩平衡
目标 亮度,对比度,色度和饱和度都是常见的视频调节参数,也是GStreamer里面设置色彩平衡的参数.本教程将展示: 如何发现可用的色彩平衡通道 如何改变它们 介绍 <GStreamer基础教程 ...
- 配置MySQL,使其与PyCharm相关联
在配置MySQL和PyCharm时,经常出现这样的错误提示: Connection to base@localhost failed. [08001] Could not create connect ...
- jira常用配置
1.关闭注册入口 系统->一般配置->运行模式:私有 2.分享给用户组是,看不到部分用户组的时候,只需要把你的账号添加该分组即可. 3.为项目分配权限,问题-->问题属性——> ...
- Jenkins+maven+gitlab自动化部署之docker发布sprint boot项目(七)
Jenkins发布docker应用与发布java应用配置基本一致,需要配置Dockerfile及构建的步骤,步骤如下: 1.jenkins主机构建应用为jar包 2.jenkins主机把生产的jar包 ...
- 剑指offer25:复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),结果返回复制后复杂链表的head。
1 题目描述 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head.(注意,输出结果中请不要返回参数中的节点引用 ...
- centos7安装php7.3的redis扩展(不是redis服务!)
PHP其他扩展加装扩展也是一样的步骤~ PHP官网下载redis扩展: http://pecl.php.net/package/redis 稳定版吧: [root@wf ~]# wget http:/ ...
- Django框架1——视图和URL配置
三个命令 1.创建一个django项目 在cmd中:django-admin.py startproject project_name D:\python\django_site>django- ...
- 【HC89S003F4开发板】 1环境搭建
HC89S003F4开发板环境搭建 一.概述 芯圣电子做活动,一个开发板只用一块钱,买过来玩玩.︿( ̄︶ ̄)︿ 全套资料可以在论坛或qq群里下载.总之先安装个环境先. 二.安装Keil C51 作为增 ...
- AJAX一些注释掉的语句
var sysdept=JSON.parse(localStorage.getItem("loginSysUser")); for(var o in sysdept){ alert ...
- skywalking 比较有意思的地方
获取agent jar包路径的方法: findPath(); private static File findPath() throws AgentPackageNotFoundException { ...