GO 学习笔记——第四天 / 面向对象

在这里插入图片描述

1.匿名组合

package main

import "fmt"

//自定义类型
type XX string

type Person struct {
	name string
	sex  bool
	age  int
}

type Student struct {
	//匿名字段
	Person
	id      int
	address string
	//同名函数
	name string
	//基础匿名字段
	XX
	//指针类型
	eat *string
}

func main() {

	//初始化
	s := Student{Person{"LGL", true, 20}, 001, "JX", "Tom", "XX", &"eat"}
	fmt.Println(s)
	//输出 {{LGL true 20} 1 JX Tom}
	//成员操作
	fmt.Println(s.name)
	//输出 Tom

	//同名函数 就近原则
	s.name = "Test"
	fmt.Println(s)
	//输出 {{LGL true 20} 1 JX Test}
	s.Person.name = "XXX"
	fmt.Println(s)
	//输出 {{XXX true 20} 1 JX Test}
}

2.方法

  • 要注意方法和函数是不一样的
  • 面向对象和面向过程的方法区别
package main

import "fmt"

//实现两数相加

//1.面向过程
func Add1(a, b int) int {
	return a + b
}

//2.面向对象
type MyNum int

//tmp:接收者,接收者就是传递的一个参数
func (tmp MyNum) Add2(other MyNum) MyNum {
	return tmp + other
}

func main() {
	fmt.Println(Add1(1, 2))

	var a MyNum = 2
	fmt.Println(a.Add2(3))
}
  • 结构体类型添加方法
  • 接收的类型不同,同名也没关系,类似重载
package main

import "fmt"

type Student struct {
	name string
	sex  bool
	age  int
}

func (tmp Student) Print() {
	fmt.Println(tmp)
}

//通过成员函数 给成员赋值
func (p *Student) Op(name string, sex bool, age int) {
	p.name = name
	p.sex = sex
	p.age = age
}

func main() {
	s := Student{"LGL", true, 18}
	s.Print()
	//输出 {LGL true 18}

	var p Student
	(&p).Op("ZS", false, 19)
	p.Print()
	//输出 {ZS false 19}
}
  • 这里也要注意一下引用传递和值传递的方法,和之前一样
package main

import "fmt"

type Student struct {
	name string
	sex  bool
	age  int
}

func (temp Student) PrintInfo() {
	fmt.Println(temp)
}

//值传递与引用传递

//接收者为普通变量 非指针 值语义 一份拷贝
func (temp Student) setInfoValues(n string, s bool, a int) {
	temp.name = n
	temp.sex = s
	temp.age = a

	fmt.Println("setInfoValues = ", temp)
	//setInfoValues =  {B false 21}
}

//接收者为指针变量 引用传递
func (temp *Student) setInfoPointer(n string, s bool, a int) {
	temp.name = n
	temp.sex = s
	temp.age = a
	fmt.Println("setInfoPointer = ", temp)
	//setInfoPointer =  &{C true 22}
}

func main() {
	s1 := Student{"A", true, 20}
	fmt.Println("1 = ", s1)
	//1 =  {A true 20}

	s1.setInfoValues("B", false, 21)
	fmt.Println("2 = ", s1)
	//2 =  {A true 20}

	s1.setInfoPointer("C", true, 22)
	fmt.Println("3 = ", s1)
	//3 =  {C true 22}
}
  • 方法集
package main

import "fmt"

type Student struct {
	name string
	sex  bool
	age  int
}

func (temp Student) SetInfoValues() {
	fmt.Println("SetInfoValues")
}

func (temp *Student) SetInfoPointer() {
	fmt.Println("SetInfoPointer")
}

func main() {
	//结构体变量是一个指针变量,它能够调用哪些方法,这些方法就是一个集合,简称方法集
	p := &Student{"Tom", false, 12}
	p.SetInfoPointer()
	//内部做了转换,先把指针p 转成*p后再调用
	p.SetInfoValues()
}
  • 方法继承
package main

import "fmt"

type Person struct {
	name string
	sex  bool
	age  int
}

//人类输出
func (temp *Person) PrintInfo() {
	fmt.Println(temp)
}

//学生 继承 人类
type Student struct {
	Person
	id      int
	address string
}

func main() {
	p := Student{Person{"A", true, 20}, 001, "jx"}
	p.PrintInfo()
	//&{A true 20}

	//方法也同样继承
}
  • 方法重写
package main

import "fmt"

type Person struct {
	name string
	sex  bool
	age  int
}

//人类输出
func (temp *Person) PrintInfo() {
	fmt.Println(temp)
}

//学生 继承 人类
type Student struct {
	Person
	id      int
	address string
}

//学生输出
func (temp *Student) PrintInfo() {
	fmt.Println(temp)
}

func main() {
	p := Student{Person{"A", true, 20}, 001, "jx"}
	p.PrintInfo()
	//&{{A true 20} 1 jx}
	p.Person.PrintInfo()
	//&{A true 20}

	//就近原则输出
}
  • 方法值:给方法调用赋值一个变量 p := Person.Println()
  • 方法表达式: 给方法名赋值一个变量 p:= Person.Println p(xxx)

3.接口

在这里插入图片描述

  • 接口的命名通常会以er结尾
  • 多态的表现
package main

import "fmt"

type Personer interface {
	Eat()
}

type Student struct {
	name string
	id   int
}

func (temp *Student) Eat() {
	fmt.Println("Eat", temp)
}

type TT struct {
	name string
	id   int
}

func (temp *TT) Eat() {
	fmt.Println("TT", temp)
}

//多态
func Who(p Personer) {
	p.Eat()
}

func main() {

	//var p Personer
	s := &Student{"LGL", 1}
	t := &TT{"TT", 1}
	//p = s
	//p.Eat()

	//只要初始类型继承此接口就可以多态
	Who(s)
	//Eat &{LGL 1}
	Who(t)
	//TT &{TT 1}

	//创建一个切片
	x := make([]Personer, 2)
	x[0] = s
	x[1] = t

	for _, i := range x {
		fmt.Println("i:", i)
	}
}
  • 接的继承口
package main

import "fmt"

type Iner1 interface {
	Eat()
}

type Iner2 interface {
	Iner1
	Sleep()
}

//定义一个学生
type Student struct {
	name string
	id   int
}

//实现吃的接口
func (temp *Student) Eat() {
	fmt.Println("Eat")
}

//实现睡觉的接口
func (temp *Student) Sleep() {
	fmt.Println("Sleep")
}

func main() {
	var i Iner2
	s := &Student{"LGL", 0}
	i = s
	i.Eat()
	i.Sleep()
}
  • 接口转换
package main

import "fmt"

//子集
type Iner1 interface {
	Eat()
}

//超集
type Iner2 interface {
	Iner1
	Sleep()
}

//定义一个学生
type Student struct {
	name string
	id   int
}

//实现吃的接口
func (temp *Student) Eat() {
	fmt.Println("Eat")
}

//实现睡觉的接口
func (temp *Student) Sleep() {
	fmt.Println("Sleep")
}

func main() {
	//接口转换 超集 ——> 子集 反之不允许
	var i1 Iner1
	var i2 Iner2
	//OK
	i1 = i2
	//NO
	i2 = i1

	fmt.Println(i1)
	fmt.Println(i2)
}
  • 空接口
func main() {
	//空接口为万能类型
	var i interface{} = 1
	fmt.Println(i)

	i = "Hello World"
	fmt.Println(i)
}
  • 类型查询
    • 断言
package main

import "fmt"

type Student struct {
	name string
	id   int
}

func main() {

	i := make([]interface{}, 3)

	i[0] = 1
	i[1] = "H"
	i[2] = Student{"lgl", 123}

	//查询类型 类型断言
	for index, data := range i {
		//第一个返回的是值  第二个是真假
		if value, ok := data.(int); ok == true {
			fmt.Println("index = ", index, "为int类型,值为:", value)
			//index =  0 为int类型,值为: 1
		} else if value, ok := data.(string); ok == true {
			fmt.Println("index = ", index, "为string类型,值为:", value)
			//index =  1 为string类型,值为: H
		} else if value, ok := data.(Student); ok == true {
			fmt.Println("index = ", index, "为Student类型,值为:", value)
			//index =  2 为Student类型,值为: {lgl 123}
		}
	}
}
- switch
//查询类型 类型断言
	for index, data := range i {

		switch value := data.(type) {
		case int:
			fmt.Println("index = ", index, "为int类型,值为:", value)
		case string:
			fmt.Println("index = ", index, "为string类型,值为:", value)
		case Student:
			fmt.Println("index = ", index, "为Student类型,值为:", value)
		}
	}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刘某人程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值