Go(三)面向对象
封装数据和行为
数据封装
结构定义
type Employee struct {
Id string
Name string
Age int
}
field后面没有逗号
实例创建及初始化
e := Employee{"", "Bob", }
e1 := Employee{Name: "Mike", Age: }
e2 := new(Employee) // 注意这里返回的引用/指针,相当于e := &Employee{}
e2.Id = "" // 与其他主要编程语言的差异,通过实例的指针访问成员不需要使用->
e2.Age =
e2.Name = "Rose"
检验一下类型
t.Logf("e is %T", e)
t.Logf("e2 is %T", e2)
=== RUN TestCreateEmployeeObj
--- PASS: TestCreateEmployeeObj (0.00s)
func_test.go:79: e is fun_test.Employee
func_test.go:80: e2 is *fun_test.Employee
PASS
行为(方法)定义
与其他主要编程语言的差异
两种方式定义行为:
// 第一种定义方式在实例对应方法被调用时,实例成员会进行值复制
func (e Employee) String() string {
return fmt.Sprintf("ID:%s-Name:%s-Age:%d", e.Id, e.Name, e.Age)
} // 通常情况下为了避免内存拷贝我们使用第二种定义方式
func (e *Employee) String() string {
return fmt.Sprintf("ID:%s/Name:%s/Age:%d", e.Id, e.Name, e.Age)
}
接口
定义交互协议
Java
如果把AClient和接口A打包在一起为packageA,Almpl打包为B
那么A和B 是相互依赖的
一般是接口独立在一个package中,解决循环依赖
Go
Duck Type式接口实现
没有显示表明实现接口,只是实现了接口的方法WriteHelloWorld()
type Programmer interface {
WriteHelloWorld() string
} type GoProgrammer struct { } func (g *GoProgrammer) WriteHelloWorld() string {
return "fmt.println(\"Hello World\")"
} func TestClient(t *testing.T) {
var p Programmer
p = new(GoProgrammer)
t.Log(p.WriteHelloWorld())
}
=== RUN TestClient
--- PASS: TestClient (0.00s)
func_test.go:117: fmt.println("Hello World")
PASS
与其他主要编程语言的差异
1.接口为非入侵性,实现不依赖于接口定义
2.所以接口的定义可以包含在接口使用者包内
接口变量
自定义类型
1.type IntConvertionFn func(n int) int
2.type MyPoint int
func timeSpent(inner func(op int)int) func(opt int) int {
return func(n int) int {
start := time.Now()
ret := inner(n) fmt.Println("time spent:", time.Since(start).Seconds())
return ret
}
}
参数特别长,自定义一个类型
type IntConv func(op int) int func timeSpent(inner IntConv) func(opt int) int {
return func(n int) int {
start := time.Now()
ret := inner(n) fmt.Println("time spent:", time.Since(start).Seconds())
return ret
}
}
扩展和复用
争议最大的一块
Go不支持继承
Java代码
class Pet {
public void speak(){
System.out.print("...");
}
public void speakTo(String name){
this.speak();
System.out.println(name);
}
} class Dog extends Pet{
@Override
public void speak(){
System.out.println("Wang!");
}
} public class InheritanceTest{ private void makePetSpeak(Pet p){
p.speak();
System.out.println("\nPet speak.");
} @Test
public void testSubClassAccess(){
Pet aDog = new Dog();
aDog.speak();
aDog.speakTo("Chao");
}
@Test
public void testLSP(){
Dog aDog = new Dog();
makePetSpeak(aDog);
}
}
makePetSpeak()的参数是Pet类型,接收子类Dog类型是可以的,且会调用Dog的speak
在Go中做同样的事情
使用内嵌
没有继承
dog只能再重写个不同的SpeakTo方法
type Pet struct { } func (p *Pet)Speak() {
fmt.Print("...")
} func (p *Pet)SpeakTo(host string) {
p.Speak()
fmt.Println(" ", host)
} type Dog struct {
p *Pet
} func (d *Dog)Speak() {
fmt.Println("Wang")
} func (d *Dog)SpeakTo(host string) {
d.Speak()
//d.p.SpeakTo(host)
fmt.Println(" ", host)
} func TestDog(t *testing.T){
dog := new(Dog)
dog.SpeakTo("chao") }
多态
想支持多态,要使用接口
空接口与断言
1.空接口可以表示任何类型
2.通过断言来将空接口转换为定制类型
v, ok := p.(int) // ok=true 时则为转换成功
func DoSomething(p interface{}) {
if i, ok := p.(int); ok{
fmt.Println("Integer", i)
return
}
if s, ok := p.(string); ok{
fmt.Println("string", s)
return
}
fmt.Println("Unknow Type")
} func TestEmptyInterfaceAssertion(t *testing.T) {
DoSomething(10)
DoSomething("10")
}
=== RUN TestEmptyInterfaceAssertion
Integer 10
string 10
--- PASS: TestEmptyInterfaceAssertion (0.00s)
PASS
用switch可以简化上面代码
func DoSomething(p interface{}) {
switch v := p.(type) {
case int:
fmt.Println("Integer", v)
case string:
fmt.Println("String", v)
default:
fmt.Println("Unknown Type")
}
} func TestEmptyInterfaceAssertion(t *testing.T) {
DoSomething(10)
DoSomething("10")
}
Go接口最佳实践
Go(三)面向对象的更多相关文章
- Javascript基础回顾 之(三) 面向对象
本来是要继续由浅入深表达式系列最后一篇的,但是最近团队突然就忙起来了,从来没有过的忙!不过喜欢表达式的朋友请放心,已经在写了:) 在工作当中发现大家对Javascript的一些基本原理普遍存在这里或者 ...
- php整理(三): 面向对象
PHP学习(三)----面向对象 首先,还是建立一个好的理解模型: 1.什么是面向对象? 面向对象分为两个部分,那就是:什么是对象和什么是面向? 什么是对象: 对象的出现就是为了用代码更好的绘制我 ...
- PHP学习(三)----面向对象
首先,还是建立一个好的理解模型: 1.什么是面向对象? 面向对象分为两个部分,那就是:什么是对象和什么是面向? 什么是对象: 对象的出现就是为了用代码更好的绘制我们现有的世界.那到底什么是对象呢? 一 ...
- Java基础学习(三)—面向对象(上)
一.理解面向对象 面向对象是一种思想,是基于面向过程而言的,就是说面向对象是将功能等通过对象来实现,将功能封装进对象之中,让对象去实现具体的细节:这种思想是将数据作为第一位,而方法或者说是 ...
- <三>面向对象分析之UML核心元素之参与者
一:版型 --->在UML里有一个概念叫版型.有些书里也称类型,构造型. --->这个概念是对一个UML元素基础定义的扩展.在同一个元素基础定义的基础上赋予特别 ...
- JavaSE-基础语法(三)-面向对象
面向对象 8.类9.对象10.封装11.继承12.多态13.构造器14.super15.this16.接口17.抽象类18.权限修饰符19.内部类
- 初识PHP(三)面向对象特性
PHP5开始支持面向对象的编程方式.PHP的面向对象编程方法和别的语言区别不大,下面对PHP面向编程基本语法进行简单记录. 一.声明对象 声明方法: class Say{ public functio ...
- ES6新增语法(三)——面向对象
ES6中json的2个变化 简写:名字和值相同时,json可以可以简写 let a=12,b=5; let json = { a, b } console.log(json) // { a:12 , ...
- JS面向对象组件(三)--面向对象中的常用属性和方法
图片的由来看下面: 1.hasOwnProperty:看是不是对象自身下面的属性 var arr = []; arr.num = ; Array.prototype.num2 = ; //所有的数组对 ...
- 精读《javascript高级程序设计》笔记三——面向对象的程序设计
重点来了,我认为这一章值得好好地反复地看.看第一遍 还是懵懵懂懂,现在看第二遍,终于能看出点意思了. 创建对象 工厂模式 function createPerson(name, age, job){ ...
随机推荐
- ERROR 1292 (22007): Truncated incorrect DOUBLE value: 'asfsda1'
mysql> UPDATE financial_sales_order SET ASSIGN_TIME = '2018-05-02 00:00:00' where CUSTOMER_ID=354 ...
- p5341 [TJOI2019]甲苯先生和大中锋的字符串
分析 TJOI白给题 建出sam,对于每个点如果它的子树siz和等于k 那么对于这个满足的点它有贡献的长度一定是一个连续区间 直接差分即可 代码 #include<bits/stdc++.h&g ...
- STM32 ADC基础与多通道采样
12位ADC是一种逐次逼近型模拟数字数字转换器.它有多达18个通道,可测量16个外部和2个内部信号源.ADC的输入时钟不得超过14MHZ,它是由PCLK2经分频产生.如果被ADC转换的模拟电压低于低阀 ...
- mysql_DML_select_union
使用union可以将多个select 语句的查询结果集组合成一个结果集.select 字段列表1 from table1union [all]select 字段列表2 from table2...说明 ...
- 测开之路六十:接口测试平台之common目录
实现接口测试平台使用jsonpath进行取值来断言,效果: 访问页面: 调试功能:http://www.kuaidi100.com/query 保存功能 触发执行功能 查看报告功能 目录结构 comm ...
- Django 的工作流程和基本内容
1.一个基本的Django请求流程 我们先开始写一个基本的请求.这个请求的获取和处理,是使用 urls.py 和 views.py 处理的.我们使用命令 python manage.py runser ...
- gcc -o hello hello.c 执行过程
GCC编译器驱动程序读取源程序文件hello.c,并将它翻译成一个可执行目标文件hello.这个翻译的过程可分为四个阶段. 1.预处理阶段 预处理器(cpp)根据以字符#开头的命令,修改原始的c程序. ...
- 厉害了,Google大神每天写多少行代码?
文章转自开源中国社区,编译自:Quora Quora上有个有趣的问题:Google工程师们每天写多少行代码? Google 的 AdMob 全栈工程师 Raymond Farias 在 Quora 发 ...
- [51nod 1766]树上的最远点对 (树的直径+ST表求lca+线段树)
[51nod 1766]树上的最远点对 (树的直径+ST表求lca+线段树) 题面 给出一棵N个点的树,Q次询问一点编号在区间[l1,r1]内,另一点编号在区间[l2,r2]内的所有点对距离最大值.\ ...
- go 协程(Goroutine)
Go 协程是什么? Go 协程是与其他函数或方法一起并发运行的函数或方法.Go 协程可以看作是轻量级线程.与线程相比,创建一个 Go 协程的成本很小.因此在 Go 应用中,常常会看到有数以千计的 Go ...