【golang/go语言】Go语言中的面向对象OOP

1. Go语言中的OOP

package main

import "fmt"


/*
面向对象:OOP
Go语言的结构体嵌套:
	1. 模拟继承性:is - a
		type A struct {
			field
		}
		type B struct {
			A // 匿名字段
		}
	2. 模拟聚合关系:has - a
		type C struct {
			field
		}
		type D struct {
			c C // 聚合关系 
		}
 */

// 定义父类
type Person struct {
	name string
	age  int
}

// 定义子类
type Student struct {
	Person // 模拟继承结构
	school string // 子类的新增属性
}

func main() {
	// 创建父类的对象
	p1 := Person{name: "zhangsan", age: 30}
	fmt.Println(p1.name, p1.age)

	// 创建子类的对象
	s1 := Student{Person{"lisi", 18}, "ECNU"}
	fmt.Println(s1)

	var s2 Student
	s2.Person.name = "wangwu"
	s2.Person.age = 28
	s2.school = "YTU"
	fmt.Println(s2)

	// 由于Person作为了Student中的匿名字段,因此Person中的字段可以通过Student直接访问,被称为提升字段
	s2.name = "zhaoliu"
	s2.age = 16
	fmt.Println(s2)
}

2. 继承中的方法

package main

import "fmt"

// 定义父类
type Person struct {
	name string
	age  int
}

// 定义子类
type Student struct {
	Person
	school string
}

func (p Person) eat() {
	fmt.Println("父类的方法,eat")
}

func (s Student) study() {
	fmt.Println("学生中学习")
}

func (s Student) eat() {
	fmt.Println("子类重写的方法,eat")
}

func main() {
	p1 := Person{"zhangsan", 30}
	fmt.Println(p1.name, p1.age)
	p1.eat()

	s1 := Student{Person{"lisi", 18}, "YTU"}
	fmt.Println(s1.name, s1.age, s1.school)
	// 当子类没重写父类方法时,可以访问父类的方法
	s1.eat()
	s1.study()
}

3. 接口

package main

import "fmt"

/*
接口:interface
	在Go中,接口是一组方法签名
	当某个类型为这个接口中的所有方法提供了方法的实现,它被称为实现接口
	Go语言中,接口和类型的实现关系是非侵入式的
*/

// 定义接口
type USB interface {
	start() // 开始工作
	end()   // 结束工作
}

// 实现类
type Mouse struct {
	name string
}

type FlashDisk struct {
	name string
}

func (m Mouse) start() {
	fmt.Println(m.name, "鼠标开始工作")
}

func (m Mouse) end() {
	fmt.Println(m.name, "鼠标结束工作")
}

func (f FlashDisk) start() {
	fmt.Println(f.name, "U盘开始工作")
}

func (f FlashDisk) end() {
	fmt.Println(f.name, "U盘结束工作")
}

func (f FlashDisk) deleteData() {
	fmt.Println(f.name, "U盘删除数据")
}

// 当需要使用接口类型的对象时,可以用任意实现类对象来代替
func testInterface(usb USB) {
	usb.start()
	usb.end()
}
func main() {
	m1 := Mouse{"逻辑"}
	testInterface(m1)

	f1 := FlashDisk{"闪迪"}
	testInterface(f1)
	f1.deleteData()

	var usb USB
	usb = m1
	usb.start()
	usb.end()
}

接口的用法:

  • 一个函数如果接受接口类型为参数,那么实际上可以传入该接口的任意实现类型对象作为参数
  • 定义一个接口类型,实际上可以赋值为任意实现类的对象

4. 接口嵌套

package main

import "fmt"

type A interface {
	test1()
}

type B interface {
	test2()
}

type C interface {
	A
	B
	test3()
}

type Cat struct {
}

func (c Cat) test1() {
	fmt.Println("test1()...")
}

func (c Cat) test2() {
	fmt.Println("test2()...")
}

func (c Cat) test3() {
	fmt.Println("test3 ()...")
}

func main() {
	var cat Cat = Cat{}
	cat.test1()
	cat.test2()
	cat.test3()

	fmt.Println("------------------------")
	var a1 A = cat
	a1.test1()

	fmt.Println("------------------------")
	var b1 B = cat
	b1.test2()

	fmt.Println("------------------------")
	var c1 C = cat
	c1.test1()
	c1.test2()
	c1.test3()
   
	fmt.Println("------------------------")
	var a2 A = c1
	a2.test1()
}

5. 接口断言

方式一:

- instance := 接口对象.(实际类型)  // 不安全,会panic()
- Instance, ok := 接口对象.(实际类型)  //安全

方式二:

switch instance := 接口对象.(实际类型) {
case 实际类型1...
case 实际类型2...
...
}

你可能感兴趣的:(Golang/Go语言,golang,java,开发语言)