原文: 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.
}
A Ferrari has this many wheels: 4

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
}
A Ferrari has this many wheels: 4
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的更多相关文章

  1. Less is exponentially more

    Less is exponentially more  (原文出处:rob pike 博客,https://commandcenter.blogspot.jp/2012/06/less-is-expo ...

  2.  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 ...

  3. 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 ...

  4. 代码的坏味道(12)——平行继承体系(Parallel Inheritance Hierarchies)

    坏味道--平行继承体系(Parallel Inheritance Hierarchies) 平行继承体系(Parallel Inheritance Hierarchies) 其实是 霰弹式修改(Sho ...

  5. 5.Inheritance Strategy(继承策略)【EFcode-first系列】

    我们已经在code-first 约定一文中,已经知道了Code-First为每一个具体的类,创建数据表. 但是你可以自己利用继承设计领域类,面向对象的技术包含“has a”和“is a”的关系即,有什 ...

  6. single-table inheritance 单表继承

    type 字段在 Rails 中默认使用来做 STI(single-table inheritance),当 type 作为普通字段来使用时,可以把SIT的列设置成别的列名(比如不存在的某个列). 文 ...

  7. C++: virtual inheritance and Cross Delegation

    Link1: Give an example Note: I think the Storable::Write method should also be pure virtual. http:// ...

  8. React之Composition Vs inheritance 组合Vs继承

    React的组合   composition: props有个特殊属性,children,组件可以通过props.children拿到所有包含在内的子元素, 当组件内有子元素时,组件属性上的child ...

  9. 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 ...

随机推荐

  1. React-native/React 公告滚动组件(原生代码)

    编写不易, 希望大家点赞 import React, {PureComponent} from 'react'; import {Animated, Easing, View} from 'react ...

  2. Beta冲刺(3/4)

    队名:秃头小队 组长博客 作业博客 组长徐俊杰 过去两天完成的任务:学习了很多东西 Github签入记录 接下来的计划:继续学习 还剩下哪些任务:后端部分 燃尽图 遇到的困难:自己太菜了 收获和疑问: ...

  3. Ubuntu 18.04 使用标准Ubuntu 仓库进行自动化安装NVIDIA驱动

    首先,检测你的NVIDIA显卡型号和推荐的驱动程序的模型.在命令行中输入如下命令: $ ubuntu-drivers devices == /sys/devices/pci0000:/::::00.0 ...

  4. springboot集成kaptcha验证码

    在pom.xml引入依赖 <!-- 验证码 --> <!-- https://mvnrepository.com/artifact/com.github.penggle/kaptch ...

  5. FutureTask源码阅读

    FutureTask功能用法 类结构 源码中详细说明了FutureTask生命周期状态及变化 /** * The run state of this task, initially NEW. The ...

  6. 循环(数组循环、获取json数据循环)、each()循环详解

    return; // 退出循环(不满足,退出此次循环.下次满足条件,依然会走此循环)return false; //退出函数(退出所有) 一. 数组循环: html: <div class=&q ...

  7. netty 实现心跳检查--断开重连--通俗易懂

    一.心跳介绍 网络中的接收和发送数据都是使用操作系统中的SOCKET进行实现.但是如果此套接字已经断开,那发送数据和接收数据的时候就一定会有问题. 1.心跳机制: 是服务端和客户端定时的发送一个心跳包 ...

  8. 在 .Net 项目中生成Report小记

    背景 项目为WinForm + WCF 的应用,按照给定格式生成Report,显示在WinForm窗体上并可以导出为PDF和Excel文件. 分析 之前用过DevExpress For WinForm ...

  9. [Xamarin] - "GenerateJavaStubs" 异常之解决

    背景 新建的 Xamarin 项目,编译失败. Error The "GenerateJavaStubs" task failed unexpectedly.Error The s ...

  10. 《Mysql - 在Mysql服务出现瓶颈时,有哪些“饮鸩止渴”提高性能的方法?》

    一:情景 - 业务高峰期,生产环境的 MySQL 压力太大,没法正常响应,需要短期内.临时性地提升一些性能. - 在业务高发时候,Mysql 服务压力过大,导致业务受损, 用户的开发负责人说,不管你用 ...