【Go】面向对象

  在Go语言中没有了class 类关键字,但是这并不代表Go语言不能使用面向对象编程,在Go语言中使用了struct关键和interface 关键字来定义对象和方法接口。具体如下:

面向对象


  Go中使用struct来定义类,假如我们需要定义一个person类,其中包含姓名、年龄等信息。我们可以使用struct关键字来定义(这个和c语言中的struct一样,只不过Go的struct支持的特性更多)

package main

import (
	"fmt"
)

type person struct {  # 定义结构体包含信息
	name string
	age int
}


func main()  { 
	s1 := person{"aa", 22}     # 初始化信息
	fmt.Println(s1)
}

  类的继承,现在假如在添加一个学生类(包含姓名、年龄、学校、班级号),我们可以使用使用类似于类中的继承的概念来使用刚才定义的person结构体。

package main

import (
	"fmt"
)

type Person struct {
	name string
	age int
}

type student struct {
	Person        # 匿名字段, 相当于继承了person的信息
	school string
	class_num int
}

func main()  {
	p1 := Person{"aa", 22}
	fmt.Println(p1)
	s1 := student{ Person{"aa", 12}, "school", 12}  # 初始化
	fmt.Println(s1)
}

  在Go语言中多继承也是可以的,就是用在需要继承的结构体中将继承的结构体添加进就完成了。例如我们定义两个基类表示信息和父母类,子类继承这两个类。

package main

import (
	"fmt"
)

type Person struct {    
	name string
	age int
}

type partent struct {
	fater string
	mother string
}

type SpeciStudent struct {
	Person
	partent
	info string
}

func main()  {
	ss := SpeciStudent{Person{"bb", 35}, partent{"bb_father", "bb_mother"}, "bb is good student"}
	fmt.Println(ss)}

  既然是类,则自然有类方法,在Go语言中方法的定义为

func (变量 结构体名) 方法名() {      # 定义方法
    方法内容
}

package main

import (
	"fmt"
)

type Person struct {
	name string
	age int
}

func (p Person) printInfo()  {
	fmt.Println(p.name, p.age)
}


func main()  {
	p1 := Person{"aa", 22}
	p1.printInfo()
}

  在面向对象中,子类可以继承父类的方法,父类不能使用子类特有的方法。在Go语言也同样遵守这个规则。

package main

import (
	"fmt"
)

type Person struct {
	name string
	age int
}

func (p *Person) printInfo()  {
	fmt.Println(p.name, p.age)
}

type student struct {
	Person
	school string
	class_num int
}

func(s student) printinfo(){
	fmt.Println(s.name, s.age, s.class_num,s.school)
}

func main()  {
	p1 := Person{"aa", 22}
	p1.printInfo()

	s1 := student{ Person{"aa", 12}, "school", 12} # 初始化子类
	s1.printInfo()     # 调用父类的方法
	s1.printinfo()   # 调用自己的方法
}

  在面向对象编程中经常使用接口, 接口好比一种模版,这个模版定义了对象必须实现的方法,其目的就是让这些方法可以作为接口实例被引用。接口不能被实例化。类可以实现多个接口并且通过这些实现的接口被索引。接口变量只能索引实现该接口的类的实例。

/ * 接口定义
  type 接口名 interface {
    方法() 返回类型
}

注意: 接口不能实例化、类中只有实现了接口的全部方法才能赋值给接口变量(否则会报错)、
*/


package main import ( "fmt" ) type Personer interface {
// 定义接口 printInfo() } type Person struct { name string age int } func (p *Person) printInfo() { fmt.Println(p.name, p.age) } func main() { var interp Personer p1 := Person{"aa", 22} interp = &p1 interp.printInfo() }

  多态的实现,在面向对象中如果传入的类型不同,函数执行的结果也不同。这里我们可以利用接口来实现多态。

	package main

	import (
		"fmt"
	)

	type Personer interface {
		printInfo()
	}

	type Person struct {
		name string
		age int
	}

	func (p *Person) printInfo()  {
		fmt.Println(p.name, p.age)
	}

	type student struct {
		Person
		school string
		class_num int
	}

	func(s student) printInfo(){
		fmt.Println(s.name, s.age, s.class_num,s.school)
	}

	func printinfo(p Personer)  {     // 定义函数,其中参数为接口类型,意味着如果传入参数的不同,我们调用的方法也将不同
		p.printInfo()
	}

	func main()  {

		p1 := Person{"aa", 22}
		printinfo(&p1)

		s1 := student{Person{"bb", 24}, "bb_school", 13 }
		printinfo(&s1)
	}

  关于接口的继承,就像和对象的继承是一样的,通过匿名字段来紧凑型设置,注意的是父接口不能转换成子接口, 但是子接口可以转换成父接口

	type Personer interface {
		printInfo()
	}

	type Personer2 interface {   // 这时 person2中拥有person中的方法,
		Personer     
		setInfo() 
	} 

  最后还有一个空接口类型,空接口就是里面花括号里面什么都没有,在Go语言中空接口变量可以接收任意类型的数据,包括整数、浮点数、函数、字符串等等。另外可以看一一下fmt.Println()函数,你会看到参数就是一个接口类型。

package main

import "fmt"

func main()  {
	type i interface {}   // 空接口类型

	var L1 i  // 定义空接口变量
	L1 = 10       //   赋值
	fmt.Println(L1)

	L1 = 1.2
	fmt.Println(L1)

	L1 = "aaaa"
	fmt.Println(L1)
}
原文地址:https://www.cnblogs.com/GoodRnne/p/10808278.html