【go】【面向对象】oop特性实现基础介绍/接口/断言

oop三大特性:继承、封装、多态

1.封装介绍
encapsulation就是把抽象出的字段和对字段的操作封装在一起,数据被保护在内部。其它包只有通过被授权的方法,才能对字段进行操作

2.封装的实现步骤

1)将结构字段的首字母小写(类似于private)
2)给结构体所在的包提供一个工厂模式的函数,首字母大写。类似于构造函数
3)提供一个首字母大写的Set方法。用于对属性判断并赋值

func (var structName) Setxxx(paraList) (retList) {
	//数据验证的业务逻辑
	var.字段 = 参数
}
  1. 提供一个Get方法,获取值
func (var structName) Getxxx() (retList) {
	return var.field
}

go并不强调封装。不像Java每个字段都必须加入get和set

3.在go中,如果struct嵌套了另一个匿名结构体,那么这个结构体可以直接访问匿名结构体的字段和方法。
在匿名结构体中定义公共的字段和方法

type Student struct{
	name string
	age int
	score int
}

func (stu *Student) showInfo() {
	fmt.Printf("Name is %v, age is %v score is %v\n",
	stu.name, stu.age, stu.score)
}

func (stu *Student) setScore(s int){
	stu.score = s
}

type Pupil struct{
	Student
}

func (p *Pupil) testing(){
	fmt.Println("Pupils are testing...")
}

type Graduate struct{
	Student
}

func (g *Graduate) testing(){
	fmt.Println("Graduates are testing")
}

func main(){
	//对结构体嵌入了匿名结构体
	pupil := &Pupil{}
	pupil.Student.name = "Tom"
	pupil.Student.age = 12
	pupil.testing()
	pupil.Student.setScore(90)
	pupil.Student.showInfo()

	g := &Graduate{}
	g.Student.name = "Mike"
	g.Student.age = 22
	g.testing()
	g.Student.setScore(80)
	g.Student.showInfo()
}

让pupil和graduate结构继承student结构

4.结构体可以使用嵌套匿名结构体(父类)的所有方法和字段,无论大小写

5.对父类的访问可以简化,不用写中间的父类名字

6.如果结构有相同的字段或方法,遵循就近原则,,先看有没有,如果没有就找父类,再没有再向上找
如果强调父类中的成员 要加上结构名

7.如果结构嵌入了多个匿名结构体,且他们含有相同的成员,且结构本身没有这一名字的成员。
此时访问必须加上父类名,否则报错

8.如果结构嵌套了一个有名结构体(struct的一个字段是另一个struct)这种模式就是组合

组合关系就必须加上结构体的名字,不能省略

9.嵌套匿名结构后,在创建实例时,可以直接指定各个匿名结构字段的值

type goods struct{
	name string
	price int
}

type brand struct{
	name string
	city string
}

type TV struct{
	//也可以嵌套指针
	//此时创建实例要加&
	goods
	brand
}

func main(){
	tv := TV{
		goods{"tv001", 3999},
		brand{"Ahri", "Harbin"},
	}

	tv2 := TV{
		goods{
			price: 25554,
			name: "tv033",
		},
		brand{
			name: "cw",
			city: "tokyo",
		},
	}
	fmt.Println(tv)
	fmt.Println(tv2)
}

10.尽量不要多重继承
11.多态主要通过接口实现
接口初体验

type usb interface{
	//声明两个没有实现的方法
	start()
	stop()
}

type phone struct{

}

//让phone实现usb的method
func (p phone) start(){
	fmt.Println("Phone starts")
}

func (p phone) stop(){
	fmt.Println("phone stops")
}

type camera struct{

}

//camera 也实现usb的方法
func (c camera) start(){
	fmt.Println("camera starts")
}

func (c camera) stop(){
	fmt.Println("camera stops")
}

type computer struct{

}

//编写一个work方法 接收usb接口类型的变量
//只要实现了usb接口 即usb接口声明的所有方法
func (c computer) work(u usb){
	//通过usb接口变量 调用start和stop方法
	u.start()
	u.stop()
}

func main(){
	cpt := computer{}
	p := phone{}
	cmr := camera{}
	cpt.work(p)
	cpt.work(cmr)
}

12.interface类型定义一组方法,不需要实现。interface不能包含任何变量。
某个结构要用的时候,再根据具体情况把方法写出来。

接口体现了多态和高内聚、低耦合的思想
实现接口必须实现接口的所有方法、方法的签名必须完全一致

对于结构本身来说,实现了接口的所有方法,结构本身并不知道实现了方法

13.接口不能单独创建实例,但是可以指向一个实现了该接口的类型的变量实例

type a interface{
	say()
}

type student struct{
	name string
}

func (stu student) say(){
	fmt.Println("student say()")
}

func main(){
	var stu student // 结构实现了a接口
	var aa a = stu
	aa.say()
}

14.只要是自定义类型,就可以实现接口。不仅是结构体
一个类型可以实现多个接口

15.一个接口A 可以继承多个别的接口B、C
这时如果要实现A接口,也必须实现BC的全部方法

16.interface默认是一个指针(引用类型)
如果没初始化就输出 会输出nil

17.空接口interface{}没有任何方法。

所有类型都实现了空接口。

如果一个函数参数是空接口,表示可以接收任何类型的任何变量

18.接口不允许有相同的方法名,包括继承而来的
19.interface的经典案例
实现sort.Sort所要求的接口

import (
	"fmt"
	"sort"
	"math/rand"
)

type hero struct{
	name string
	age int
}

type heroSlice []hero

func (hs heroSlice) Len()int {
	return len(hs)
}

//按age从小到大排序
func (hs heroSlice) Less(i, j int) bool{
	return hs[i].age < hs[j].age
	//return hs[i].name < hs[j].name
}

func (hs heroSlice) Swap(i, j int){
	tmp := hs[i]
	hs[i] = hs[j]
	hs[j] = tmp
	// hs[i], hs[j] = hs[j], hs[i]
}

func main(){
	//define a slice
	var intSlice = []int{2, 5, 6, -1, 4}
	//slice是引用类型
	sort.Ints(intSlice)
	fmt.Println(intSlice)

	var heroes heroSlice
	for i := 0; i < 10; i++ {
		h := hero{
			name: fmt.Sprintf("hero-%d", rand.Intn(100)),
			age: rand.Intn(5000),
		}
		heroes = append(heroes, h)
	}
	//sequence before sort
	for _, v := range heroes{
		fmt.Println(v)
	}
	fmt.Println("---------------------")
	sort.Sort(heroes)
	//sequence after sort
	for _, v := range heroes{
		fmt.Println(v)
	}
}

20。接口一定程度上实现代码解耦
21.接收接口的函数,根据传入实参的不同,就具备不同的功能。体现了多态
22.将空接口类型赋值给其它类型需要使用类型断言

	var x interface{}
	var a float32 = 1.3
	x = a // 空接口接收任意类型
	
	if y, ok := x.(float32); ok {
		fmt.Println("convert success")
		fmt.Printf("type of y is %T y = %v\n", y, y)
	}else{
		fmt.Println("convert failed")
	}
	fmt.Println("go on")

23.断言sample

type usb interface{
	//声明两个没有实现的方法
	start()
	stop()
}

type phone struct{
	name string
}

//让phone实现usb的method
func (p phone) start(){
	fmt.Println("Phone starts")
}

func (p phone) stop(){
	fmt.Println("phone stops")
}

func (p phone) call(){
	fmt.Println("calling")
}

type camera struct{
	name string
}

//camera 也实现usb的方法
func (c camera) start(){
	fmt.Println("camera starts")
}

func (c camera) stop(){
	fmt.Println("camera stops")
}

type computer struct{

}

//编写一个work方法 接收usb接口类型的变量
//只要实现了usb接口 即usb接口声明的所有方法
func (c computer) work(u usb){
	//通过usb接口变量 调用start和stop方法
	u.start()
	if p, ok := u.(phone); ok {
		p.call()
	}
	u.stop()
}

func main(){
	var usbArr [3]usb
	usbArr[0] = phone{"vivo"}
	usbArr[1] = phone{"xiaomi"}
	usbArr[2] = camera{"canon"}
	var c computer
	for _, v := range usbArr{
		c.work(v)
		fmt.Println()
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值