Go语言---面向对象编程

Go语言的语言设计非常的简洁,因为,Go语言并没有面向对象的概念,因此Go语言中没有面向对象的一些概念,例如(封装、继承、多态,虚函数、构造函数,this指针等)
尽管Go语言中没有封装、继承、多态,但同样也可以实现相应的功能。
封装:通过方法进行实现
继承:通过匿名字段实现
多态:通过接口实现

方法

方法也是一种函数类型,本质上,一个方法则是一个和特殊类型关联的函数
在这里插入图片描述

type Int int
//a为接收者,Int为接收者的名字
func (a Int)add(b Int)Int{
    
    
	return a+b
}

func main(){
    
    
	var a Int = 3
	res := a.add(2)
	fmt.Println(res)
}

同时,可以通过方法为结构体变量赋值。

type Person struct{
    
    
	Name string 
	Age int 
}

func (P Person)PrintInfo(){
    
    
	//...一些基本操作
}

我们可以通过函数为结构体进行赋值操作。

type Person struct{
    
    
	Name string 
	Age int 
}

func (P *Person)SetInfo(s string,i int){
    
    
	P.Name = s
	P.Age = i
}
func main(){
    
    
	var p Person
	(&p).SetInfo("bai",20)
	fmt.Println(p.Name,p.Age)
}

方法类似于多了一个参数,我们可以将接受方法看成一个参数。
在这里插入图片描述
注意

  • 自定义类型不能为指针类型
    -
  • 接收者类型不同,同名也不会出现错误。
    在这里插入图片描述

匿名字段

type person struct{
    
    
	Name string 
	Age int
}

type Student struct{
    
    
	person  //只有类型,没有具体名称
	className string
}

上面的Student类中,包含person的匿名字段,相当于继承于person。

初始化方式:

  • 顺序初始化
    s1 := Student{person{"bai",20},"xiaan"}
  • 指定成员初始化
    s2 := Student{className:"xiaan"}
    s3 := Student{person:person{Name:"bai"},className:"xiaan"}

结构体指针类型匿名字段

type person struct{
    
    
	Name string 
	Age int
}

type Student struct{
    
    
	*person  //指针类型
	className string
}

初始化操作

  • 直接赋值
    s1 := Student{&person{"bai",20},"xiaan"}

  • 先初始化,在赋值

var s1 Student
s1.person = new (person)
s1.Name = "bai"
s1.Age = 20
s1.className = "xiaan"

接口

Go语言中使用接口实现多态的效果。

接口的定义:

type 接口名 interface{
    
    
	接口声明
}

例如:HelloWorld接口的定义

type Hello interface{
    
    
	HelloWorld() //只声明,不实现
}

HelloWorld接口的实现

//通过自定义类型实现接口
type Student struct{
    
    
	name string 
	age int
}

func (s *Student)HelloWorld(){
    
    
	fmt.Printf("Student [%s %d]",s.name,s.age)
}

//默认类型实现接口
type Int int 
func (i *Int)HelloWorld(){
    
    
	fmt.Printf("I")
}

HelloWorld接口的调用

//自定义类型调用接口
s := &Student{
    
    "xiao",20}
var h Hello
h = s
h.HelloWorld()

//默认类型调用接口
var i Int
h = i
h.HelloWorld()
常见多态的实现方式
  • 定义一个函数,函数的参数类型为接口类型
//多态:只有一个函数,实现不同功能
func Test(h Hello){
    
    
	h.HelloWorld()
}

func main(){
    
    
	s := &Student{
    
    "xiao",20}
	Test(s)
]

接口的继承

type Humaner interface{
    
    
	Hello() //定义一个Hello接口	
}

type Person interface{
    
    
	Humaner //匿名字段,接口的继承
	HelloWoeld(str string)
}

//自定义数据类型
type Student struct{
    
    
	name string 
	age int 
}
//Hello接口的实现
func (s *Student)Hello(){
    
    
	fmt.Printf("name= %s age%d=",s.name,s.age)
}	

//HelloWorld接口的实现
func (s *Student)HelloWorld(str string){
    
    
	fmt.Printf("str name=%s age%d ",s.name,s.age)
}

//接口的调用
func main(){
    
    
	var p Person
	s := &Student{
    
    "bai",20} //实例化一个结构体
	p = s
	p.Hello() //调用继承的Hello接口
	p.HelloWoeld() //调用自身的HelloWorld接口
}

接口的转换

在这里插入图片描述
超级可以转换为子集,子集不能转换为超集。

var p Person //超集
var h Humaner //子集
p = h //错误
h = p //正确
空接口

空接口不包含任何方法,因此,所有的类型都可以实现空接口。
空接口可以存储任何类型的值

var v1 interface{
    
    } = 1 //将int类型赋值给空接口
var v2 interface{
    
    } = "abc" //将string类型赋值给空接口

空接口也可以作为函数的参数,表示该函数可以接收任意类型。常见的fmt函数就是一个空接口函数

类型查询

由于空接口函数可以接收任意类型的参数,因此需要类型查询。常见类型查询的办法为类型断言

//定义一个空接口切片
i := make([]interface{
    
    },3)
i[0] = 1
i[1] = "abc“
i[2] = Student{"bai",20}


//if -- else类型断言
//for循环:index为下标,data为具体的值分别是i[0],i[1],i[2]
for index,data := range i{
    
    
	//value为具体的值,ok为true时表示判断正确,ok为false表示判断错误
	if value,ok := data.(int) == true{
    
    
	}
}


//switch 类型断言
for index,data := range i{
    
    
	switch value:= data.(type){
    
    
		case  int:
			...
		case string:
			...
		case struct:
			...
	}
}

猜你喜欢

转载自blog.csdn.net/qq_42708024/article/details/107152795