【玩转Golang】 通过组合嵌入实现代码复用
应用开发中的一个常见情景,为了避免简单重复,需要在基类中实现共用代码,着同样有助于后期维护。
如果在以往的支持类继承的语言中,比如c++,Java,c#等,这很简单!可是go不支持继承,只能mixin嵌入,且看下面的代码:
type ManKind interface{
Say(s string);
GetMouth()string
}
type Man struct{
}
func NewMan() ManKind{
return &Man{};
}
func (this *Man)GetMouth()string{
return "M0"
}
func (this *Man) Say(s string){
fmt.Printf("\n Speak with mouth[%s] : \"%s\"",this.GetMouth(),s);
}
type StrongMan struct{
Man
}
func NewStrongMan()ManKind{
return &StrongMan{}
}
func (this*StrongMan)GetMouth()string{
return "M1"
}
func main(){
NewMan().Say("good luck!")
NewStrongMan().Say("good luck!")
}
如果支持继承,很明显应该输出
Speak with mouth[M0] : "good luck!"
Speak with mouth[M1] : "good luck!"
但是在golang中只能输出:
Speak with mouth[M0] : "good luck!"
Speak with mouth[M0] : "good luck!"
StrongMan中调用Say(),此时可以将指针传递到内嵌类,只是简单的指向了Man的方法,在ManKind中调用GetMouth就是ManKind自己的GetMouth,和StrongMan没有关系。
当然,我们可以在StrongMan中覆盖Say方法
func (this *StrongMan)Say(s string){
fmt.Printf("\n Speak with mouth[%s] : \"%s\"",this.GetMouth(),s);
}
此时,当然可以正确输出,因为本来调用的就都是StrongMan自己的方法了,这又和我们的初衷相违背了。那么这种情况怎么实现呢?我的方法是,让Man再脏一点儿,把需要的东西传递给组合进来的类。
给Man增加一个属性mouth,增加一个SetMouth方法,修改一下GetMouth方法,StrongMan的GetMouth方法删除掉,再修改一下NewStrongMan方法,最后的代码如下:
package main import(
"fmt"
) type ManKind interface{
Say(s string);
SetMouth(m string)
GetMouth()string
}
type Man struct{
ManKind
mouth string
}
func NewMan() ManKind{
return &Man{mouth:"M0"};
}
func (this *Man)GetMouth()string{
return this.mouth;
}
func (this *Man)SetMouth(s string){
this.mouth=s;
}
func (this *Man) Say(s string){
fmt.Printf("\n Speak with mouth[%s] : \"%s\"",this.GetMouth(),s);
}
type StrongMan struct{
Man
}
func NewStrongMan()ManKind{
sm := &StrongMan{}
sm.SetMouth("M1");
return sm;
} func main(){
NewMan().Say("good luck!")
&NewStrongMan().Say("good luck!")
}
当然,如果你不愿意用Get、Set方法,也可以直接输出Man的Mouth属性。
我总结的嵌入式编程要点:
1,被嵌入的类的方法,只能访问他自己的字段,包装类即时声明了同名字段也没用。
2,包装类可以覆盖嵌入类的方法,但是嵌入类访问不到,亦然访问自己的方法。只能在包装类中连同调用方法一同实现。
3,包装类覆盖嵌入类字段后,亦然可以通过嵌入类的类名访问嵌入类的字段。
【玩转Golang】 通过组合嵌入实现代码复用的更多相关文章
- C++进阶--代码复用 继承vs组合
//############################################################################ /* * 代码复用: 继承 vs 组合 * ...
- 实验四——使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用
实验目的: 使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用 实验过程: 查看系统调用列表 get pid 函数 #include <stdio.h> #include & ...
- go.rice 强大灵活的golang 静态资源嵌入包
以前简单介绍过packr ,statik 等静态资源嵌入工具包的使用,go.rich 是一个与packr 类似的静态资源嵌入包,使用简单 功能强大 项目结构 golang mod go mod i ...
- golang拾遗:嵌入类型
这里是golang拾遗系列的第三篇,前两篇可以点击此处链接跳转: golang拾遗:为什么我们需要泛型 golang拾遗:指针和接口 今天我们要讨论的是golang中的嵌入类型(embedding t ...
- linux内核分析作业4:使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用
系统调用:库函数封装了系统调用,通过库函数和系统调用打交道 用户态:低级别执行状态,代码的掌控范围会受到限制. 内核态:高执行级别,代码可移植性特权指令,访问任意物理地址 为什么划分级别:如果全部特权 ...
- 在Flex (Flash)中嵌入HTML 代码或页面—Flex IFrame
在flex组件中嵌入html代码,可以利用flex iframe.这个在很多时候会用到的,有时候flex必须得这样做,如果你不这样做还真不行-- flex而且可以和html进行JavaScript交互 ...
- JSP中嵌入java代码方式以及指令
JSP中嵌入java代码的三种方式: (1)声明变量或方法 : <%! 声明; %> :慎重使用,因为此方法定义的是全局变量 (2)java片段(scriptlet): <% j ...
- 网页嵌入WMP代码(转)
网页嵌入WMP代码 播放器代码解释,装了9.0或9.0以上的播放器才能正常使用: OBJECT id="WMP" height="176" width=&quo ...
- Delphi代码中嵌入ASM代码
前言 Delphi作为一个快速高效的开发平台,使用的人越来越多,但熟悉在Delphi代码中嵌入ASM代码的程序员我想不多,因为这方面的资料太少了,另一方面,它还需要有基本的汇编语言知识,关於汇编语言的 ...
随机推荐
- tomcat8.5性能优化
主要是按照两篇文章,部分参数因适配Tomcat8.5进行了调整 一.有关 JAVA_OPTS http://www.open-open.com/lib/view/open1401931407228.h ...
- 基于html5顶部导航3D翻转展开特效
基于html5顶部导航3D翻转展开特效是一款基于jQuery+HTML5实现的3D翻转网站导航菜单代码.效果图如下: 在线预览 源码下载 实现的代码. html代码: <header cla ...
- python matplotlib 画图
import numpy as np import matplotlib.pyplot as plt from pylab import * numpy 常用来组织源数据: 使用 plot 函数直接绘 ...
- JedisConnectionPool scala
/** * Created by lq on 2017/8/29. */ object JedisConnectionPool { val config = new JedisPoolConfig() ...
- ContentType和@ResponseBody
ContentType 为 application/x-www-form-urlencoded (表单)时,入参前不需要加@ResponseBody: ContentType 为 applicatio ...
- Java FutureTask<V> 源码分析 Android上的实现
FutureTask类提供了可取消的异步计算,并且可以利用开始和取消计算的方法.查询计算是否完成的方法和获取计算结果的方法. 首先看一下继承关系 public class FutureTask< ...
- 使用taskset命令来限制进程的CPU
常常感觉系统资源不够用,一台机子上跑了不下3个比较重要的服务,但是每天我们还要在上面进行个备份压缩等处理,网络长时间传输,这在就很影响本就不够用的系统资源: 这个时候我们就可以把一些不太重要的比如co ...
- css 可穿透
pointer-events : none; 引自:http://www.thinkphp.cn/topic/4702.html
- R语言进行数据预处理
R语言进行数据预处理wranging li_volleyball 2016年3月22日 data wrangling with Rpackages:tidyr dplyr Ground rules l ...
- 【转】Windows 7 API Internet Connection Sharing(ICS) 与 Wireless Hosted Network构建本地AP
原文:http://hi.baidu.com/ritrachiao/item/bf7715e6bb8cb3a0c10d75be [此刻我要大大地记录一下!] 这个折腾了我好几天的Windows 7 A ...