这是我参与「第五届青训营」伴学笔记创作活动的第 3 天
Go的封装,继承和多态(面向对象三大特性
封装
Go中的封装和Java的不太一样,在Go里面是没有Java中的类class,不过可以把结构体struct看成一个类(昨天说过),封装可以简单地看作对struct的封装,如下:
type stru1 struct {
value1 string
}
type stru2 struct {
value2 string
}
继承
把struct看做class,struct中可以包含其他的struct,继承内部struct的方法和变量,同时可以重写(其实重写也是一种多态,我们一般将其称为静态多态),下面举一个例子:
package main
import "fmt"
type outer struct {
inner
s1 string
n2 int
b3 bool
}
type inner struct {
s2 string
}
func (u *inner) testMethod(){
fmt.Println("testMethod is called!!!")
}
func main() {
out1 := new(outer)
fmt.Println("s2无值:"+out1.s2)
out1.s2 = "abc"
fmt.Println("s2已赋值"+out1.s2)
out1.testMethod()//继承调用
out1.inner.testMethod()//继承调用 这里也可以重写
}
与我们一般的想法不一样的是,外层的结构体是子结构体,内部的是父结构体。
多态
Go中的多台比Java的隐匿得多,其多态不需要继承,只要实现了相同的接口即可,对于都实现了同一接口的两种对象,可以进行类似地向上转型,并且在此时可以对方法进行多态路由分发,这点其实自己没有用代码实现过,从网上找了一段代码:
package main
import "fmt"
type interfacetest interface {
//testMothod1() string
//testMothod()//这种会报语法错误 在go里面是不允许的
iMethod() //加上int则会报错 说明go的方法判断有返回值,而java没有
}
type obj1 struct {
valte1 string
}
type obj2 struct {
valte2 string
}
//从属不同对象的testMothod 返回值不同的接口实现
func ( obj11 *obj1)iMethod(){
fmt.Println("testMothod go obj1")
}
//从属不同对象的testMothod 返回值不同的接口实现
func ( obj11 *obj2)iMethod() {
fmt.Println("testMothod go obj2")
}
func gorun(ii interfacetest){
fmt.Println(ii.iMethod)
}
func main(){
var i interfacetest
//interfacetest_ := new(interfacetest)//这种方式进行多台路由转发会报错 GO需先声明 如 var i interfacetest
obj1_ := new(obj1)
//赋obj1
i = obj1_
i.iMethod()//正确打印
gorun(i)
gorun(obj1_)
//interfacetest_.testMethod() //这种在java中允许,在go中是不允许的
//赋obj2
obj2_ := new(obj2)
i = obj2_
i.iMethod()//正确打印
gorun(i)
gorun(obj2_)
list := [2]interfacetest{obj1_,obj2_}
slice := []interfacetest{}
slice = append(slice, obj1_)
slice = append(slice, obj2_)
for index,value := range slice {
fmt.Println(index)
fmt.Println(value)
}
fmt.Println(len(slice))
fmt.Println(len(list))
}
这一块没怎么了解过,因为在Java里面除了自己定义API,还没有怎么用过interface……
收尾
这几天都在摆烂式学习,还是主要以Java为主,Go的学习我觉得可以一直持续到工作后,有可能是Java导致自己习惯的语法固化了,自己又没有到那种随心所欲的境界,作为一个在校生Go只能当一个学着玩玩的东西了。