go面向对象2

类属性和成员方法可见性  

不管是变量、函数,还是自定义类的属性和成员方法,它们的可见性都是根据其首字母的大小写来决定的,如果变量名、属性名、函数名或方法名首字母大写,就可以在包外直接访问这些变量、属性、函数和方法,否则只能在包内访问,因此 Go 语言类属性和成员方法的可见性都是包一级的

通过首字母大小写来控制

 

通过私有化提示代码的安全性

通过定义构造函数来封装他们的初始化过程,然后把属性名首字母小写进行私有化

animal.go

package animal

type Animal struct{

  name string

}

func NewAnimal(name string) Animal {

  return Animal{name:name}

}

func (a Animal) Call() string {

  return "动物的叫声"

}

func (a Animal) FavorFood() string {

  return "爱吃的食物"

}

func  (a Animal) GetName() string {

  return a.name

}

//属性名称首字母变成小写了,变成了私有的了 

要完成类的初始化 需要调用构造函数来实现

 animail := NewAnimal("中华田园犬")

 

 

接口定义及实现

一个类只要实现了某个接口要求的所有方法,我们就说这个类实现了该接口

定义一个类  File  并实现  Read  Write  Seek  Close()

type File struct{

  

}

func (f *File) Read(buf []byte) (n int,err error)

func (f *File)  Write(buf []byte) (n int,err error)

func (f *File) Seek(off int64) (pos int64,err error)

func (f *File) Close() error

go语言通过关键字 interface  来声明接口 ,花括号内包含的是待实现的方法集合

type IFile interface {

  Read(buf []byte)(n int,err error)

  Write(buf []byre) (n int,err error)

  Seek(off int64,whence int) (pos int64,err error)

  Close() error

}

 

type IReader interface {

  Read(buf []byte) (n int, err error)

}

File实现了这些接口  因为file 实现了上述所有接口声明的方法

 

通过组合实现接口继承

go也支持类似接口继承的特性  通过组合来完成

例子

type A interface {

  Foo()

}

type B interface {

  A

  Bar()

}

然后我们定义一个类 T 实现接口 B 

type T strcut {}

 

func (t T) Foo(){

  fmt.Println("call Foo funciton from interface a")

}

func (t T) Bar(){

  fmt.Println("call bar function from interface b")

}

 

接口组合是匿名类型组合的一个特定的场景(没有显式的为组合类型设置对应的属性名称) 只包含方法 不包含属性

例子

type Reader interface{

  Read(p []byte)(n int,err error)

}

type Writer interface{

  Write(p []byte) (n int, err error)

}

 

type ReadWriter interface {

  Reader

  Writer

}

 

六 , 接口赋值

接口赋值在go分为2种情况

1 将实现接口的类实例赋值给接口

2将一个接口赋值给另外一个接口

 

将类实例赋值给接口

只包含值方法

 

********在这补上为值类型定义成员方法 *********

Go 语言中的大多数类型都是值语义,包括:

  • 基本类型,如布尔类型、整型、浮点型、字符串等;
  • 复合类型,如数组、结构体等(切片、字典、指针和通道都是引用语义)
  • Go 语言中的大多数类型都是值语义,包括:

    • 基本类型,如布尔类型、整型、浮点型、字符串等;
  • 复合类型,如数组、结构体等(切片、字典、指针和通道都是引用语义)

所有值语义类型都支持定义成员方法,包括内置基本类型。例如,我们可以为整型新增比较方法 Equal

不过在此之前,需要将基本类型通过 type 关键字设置为新的类型:

type  Integer int

func (a Integer)  Equal(b Interger) bool{

  return a == b

}

*********end********

 

type Integer int  //为基本类型添加成员方法时定义过的Integer类

func (a Integer)  Add(b Integer) Integer {

  return a+b

}

func (a Integer) Multiplay(b Integer) Integer {

  return a*b

}

type Math interface {

  Add(i Integer) Integer

  Multiplay(i Integer) Integer

}

Integer类型实现了 Math接口  然后我们 就可以把Integer 类型的实例a 赋值给Math接口类型变量m

var a Integer  =1

var m Math = a

fmt.Println(m.Add(1))

 

对于值方法  进行接口赋值时传递 a实例的指针引用也是可以的 

var  a Integer  =1 

var m Math = &a

fmt.Println(m.Add(1))

因为对于非指针方法 go底层会自动生成一个与之对于的指针成员方法

func (a *Integer) Add()

func (a *Integer) Multiplay( i Integer) Integer{

  return (*a).Multiplay(i)

包含指针方法,接口赋值时 就只能传递指针类型的变量了

type Integer int

func (a *Integer) Add(b Integer){

  *a = *a +b 

}

var a Interger =1

var m Math = &a

 

将接口赋值给接口

在go语言中 只要2个接口拥有相同的方法列表  那么他们就是等同的  可以相互赋值

 

方法子集

如果接口a的方法列表是接口b方法列表的子集 那么接口b 可以赋值给接口a

posted @ 2021-04-12 17:39  fly_fly_fly#  阅读(60)  评论(0编辑  收藏  举报