首页 > 编程语言 >狂神说Go语言—面向对象编程讲解

狂神说Go语言—面向对象编程讲解

时间:2022-12-28 20:34:30浏览次数:42  
标签:func int fmt 接口 Println 面向对象编程 Go 狂神 type

OOP思想

Go语言不是面向对象语言,只是让大家理解一些面向对象的思想,通过一些方法来模拟面向对象

语言的进化发展跟生物的进化发展是一回事,都是"物以类聚"

语句多了,我们将完成同样功能相近的语句,聚到一块,便于我们使用,于是,函数出现了

变量多了,我们将功能相近的变量组在一起,聚到一起归类,便于我们调用。于是,结构体出现了

再后来,方法多了,变量多了!结构体不够用!我们就将功能相近的变量和方法聚到了一起,于是类和对象就出现了

企业的发展也是"物以类聚"的过程,完成市场维护的人员聚到了一起形成了市场部。完成技术开发的人员聚到了一起形成了开发部

面向对象的思维模式

面向对象的思维模式是简单的线性思维,思考问题首先陷入第一步做什么,第二步做什么的细节中,这种思维模式适合处理简单的事情,比如:上厕所

如果面对复杂的事情,这种思维模式会陷入令人发疯的状态!比如:如何造火箭!

面向对象的思维模式

面向对象的思维模式说白了就是分类思维模式,首先思考解决问题,需要哪些分类,然后对这些分类进行单独思考。最后,才对某个分类下的细节进行面向过程的思索

这样就可以形成很好的协作分工。比如:架构师分了10个类,然后将10个类交给了10个人分别进行详细设计和编码!

显然,面向对象适合处理复杂的问题,适合处理需要多人协作的问题!

如果一个问题需要多人协作一起解决,那么你一定要用面向对象的方式来思考!

对于描述复杂的事物,为了从宏观上把握、从整体上合理分析,我们需要使用面向对象的思路来分析整个系统。但,仍然需要面向过程的思路去处理。
面向对象的三大特点:封装、继承、多态I

继承

image-20221228100447165

兔子和羊属于食草动物类,狮子和豹属于食肉动物类。

食草动物和食肉动物又是属于动物类。
所以继承需要符合的关系是: is-a,父类更通用,子类更具体。
虽然食草动物和食肉动物都是属于动物,但是两者的属性和行为上有差别,所以子类会具有父类的一般特性也会具有自身的特性。
继承就是子类继承父类的特征和行为,使得子类具有父类的属性和方法,使得子类具有父类相同的行为。子类会具有父类的一般特性也会具有自身的特性。

package main

import "fmt"

	/*
	Go语言的结构体嵌套
	 1、模拟继承性:is - a
	type A struct{
	field
	}
	type B struct{
	A//匿名字段
	//b就可以直接访问a的属性了
	}
	2、模拟聚合关系:has -a
	 type C struct{
		field
	}
	 type D struct{
		c	C  //聚合关系
	}
		//D就不能直接访问c当中的属性,需要通过D.C.xx访问
	}
	*/
// 定义一个父类结构体
type Person struct {
	name string
	age  int
}

// 定义一个子类结构体
type Student struct {
	Person //匿名结构体
	school string
}

func main() {
	//创建一个父类的对象
	p1 := Person{"张三", 18}
	fmt.Println(p1)

	//创建一个子类的对象
	s1 := Student{Person{"秦疆", 18}, "清华"}
	fmt.Println(s1.Person.name)
	fmt.Println(s1.name)

	//	提升字段
	//	对于student来说,person是匿名字段,person中的属性name,age就叫做提升字段
	//	 提升字段可以通过名字直接访问,不需要再通过结构体名person
	var s3 Student
	s3.name = "kuangshen"
	s3.school = "北大"
	fmt.Println(s3)
}

/*
{张三 18}
秦疆
秦疆
{{kuangshen 0} 北大}
*/

方法讲解

什么是方法

Go语言中同时拥有函数和方法

  • 方法:
    • 某个类别的行为功能。需要指定接收者调用
    • 一段独立的功能代码,可以直接调用
  • 函数
    • 一段独立功能的代码,可以直接调用
    • 命名不能冲突
package main

import "fmt"

// 定义一个Dog的结构体
type Dog struct {
   name string
   age  int
}

// 定义一个Cat的结构体
type Cat struct {
   name string
   age  int
}

// 定义方法,接受者为Dog类型
func (dog Dog) eat() {
   fmt.Println("dog...eating")
}
func (dog Dog) sleep() {
   fmt.Println("dog..sleep")
}
func (cat Cat) eat() {
   fmt.Println("cat...eating")
}
func main() {
   //接收者对象dog,设置结构体的属性
   dog := Dog{"二哈", 3}
   //调用方法
   dog.eat()
   dog.sleep()

   cat := Cat{"TD", 5}
   cat.eat()
}
/*
dog...eating
dog..sleep
cat...eating
*/

方法重写

子类可以重写父类的方法override

子类可以新增自己的属性和方法

子类可以直接访问父类的属性和方法

package main

import (
   "fmt"
)

type Animal struct {
   name string
   age  int
}

// 同一包下结构体重名 +s
type Dogs struct {
   Animal
   sex string
}
type Cats struct {
   Animal
   color string
}

func (animal Animal) eat() {
   fmt.Println("吃吃吃~~~")
}
func (animal Animal) sleep() {
   fmt.Println("睡觉觉~~~")
}

// 方法的重写
func (dogs Dogs) eat() {
   fmt.Println("dog正在吃吃吃~~~")
}
func (cats Cats) sleep() {
   fmt.Println(cats.name, "正在睡觉觉~~~")
}

func main() {
   dog := Dogs{Animal{"旺财", 3}, "公"}
   dog.Animal.eat() //调用父类方法
   dog.eat()        //调用父类重写之后的方法

   cat := Cats{Animal{"TD", 2}, "red"}
   cat.sleep()
}
/*
吃吃吃~~~
dog正在吃吃吃~~~
TD 正在睡觉觉~~~
*/

接口实现

Go语言提供了另外一种数据类型即接口,它把所有的具有共性的方法定义在一起,任何其他类型只要实现接口定义的全部方法就是实现了这个接口

接口只做定义,不做具体的方法实现,具体实现交给实现方法

// go语言不需要显示的接口
// 实现接口中的方法,就算实现了接口
// go语言中,接口和实现类的关系,是非侵入式的

package main

import "fmt"

// 定义一个USB的接口,以及接口中有两个方法
type USB interface {
   oInput()
   oOutput()
}

// 定义一个Mouse鼠标结构体
type Mouse struct {
   name string
}

// 接口方法实现,当接口中的所有方法都被调用时旁边才会出现I图标
func (mouse Mouse) oInput() {
   fmt.Println(mouse.name, "鼠标输入")
}
func (mouse Mouse) oOutput() {
   fmt.Println(mouse.name, "鼠标输出")
}

// 示列二:定义一个Keyboard键盘结构体
type Keyboard struct {
   name string
}

func (k Keyboard) oInput() {
   fmt.Println(k.name, "键盘输入")
}
func (k Keyboard) oOutput() {
   fmt.Println(k.name, "键盘输出")
}

// 测试方法  传递一个USB的对象,这里也可以传入一个Mouse的对象
func test(u USB) {
   //将传入的对象调用方法
   u.oInput()
   u.oOutput()
}
func main() {
   //通过传入接口实现类,来进行具体方法的调用
   m := Mouse{"罗技"}
   //调用测试方法
   test(m)

   k := Keyboard{"雷蛇"}
   test(k)

   var u USB
   u = k
   fmt.Println(u)
   //fmt.Println(u.name) 这里会报错,只能给予赋值,不能赋予属性
}
/*
罗技 鼠标输入
罗技 鼠标输出
雷蛇 键盘输入
雷蛇 键盘输出
{雷蛇}
*/

多态

多态:一个事务拥有多种形态,是面向对象中很重要的一个特点

Go语言通过接口来模拟多态

package main

import "fmt"

// 定义一个Animal2接口
type Animal2 interface {
   eat()
   sleep()
}

// 定义结构体
type Dog2 struct {
   name string
}

// 方法实现
func (dog2 Dog2) eat() {
   fmt.Println(dog2.name, "eat..")
}
func (dog2 Dog2) sleep() {
   fmt.Println(dog2.name, "sleep..")
}

// 测试方法 接收Animal2的参数对象
func test2(animal2 Animal2) {
   fmt.Println("test2")
}
func main() {
   //Dog2
   dog2 := Dog2{"哈士奇"}
   dog2.eat()
   dog2.sleep()
   //Animal2
   test2(dog2)
}
/*
哈士奇 eat..
哈士奇 sleep..
test2
*/

空接口

不包含任何的地方,正因为如此,所有的类型都实现了空接口,因此空接口可以存储任意类型的值

package main

import "fmt"

type Dog3 struct {
   name string
}
type Cat3 struct {
   name  string
   color string
}

func test3(a A) {
   //接收参数打印输出,这里如果是test3,则为test3的地址
   fmt.Println(a)
}
func test4(in interface{}) {
   fmt.Println(in)
}

// 空接口
type A interface {
}

func main() {
   a1 := Dog3{"大黄"}
   a2 := Cat3{"喵喵", "白色"}
   var a3 A = "嘿嘿嘿"
   var a4 A = 100
   a5 := A("heh")

   fmt.Println(a1)
   fmt.Println(a2)
   fmt.Println(a3)
   fmt.Println(a4)
   fmt.Println(a5)

   test3(a1)
   test3(a2)
   test3(a3)
   // map  通过make函数创建 类型为map 输入类型为string 传入参数为interface{}任意类型
   map1 := make(map[string]interface{})
   map1["name"] = "旺财"      //传参为string类型
   map1["age"] = 18         //传参为int
   map1["dog"] = Dog3{"二哈"} //传参为对象
   fmt.Println(map1)

   // 切片
   s1 := make([]interface{}, 0, 10)                     //切片类型,存储对象为interface{}任意类型,长度为0,容量为10
   s1 = append(s1, a1, a2, a3, a4, a5, "hhhhhhh", 1000) //可以将其他参数添加进去,也可以自行创建添加
   fmt.Println(s1)
}
/*
{大黄}
{喵喵 白色}
嘿嘿嘿
100
heh
{大黄}
{喵喵 白色}
嘿嘿嘿
map[age:18 dog:{二哈} name:旺财]
[{大黄} {喵喵 白色} 嘿嘿嘿 100 heh hhhhhhh 1000]

*/

接口嵌套

接口可以继承,还可以多继承

package main

import "fmt"

type A2 interface {
   testa()
}
type B2 interface {
   testb()
}

// C2继承A2和B2接口
type C2 interface {
   A2
   B2
   testc()
}
type Dogg struct {
}

// 要实现testc的方法吧,必须先实现testb和testa
func (dogg Dogg) testc() {
   fmt.Println("testc")
}
func (dogg Dogg) testb() {
   fmt.Println("testb")
}

func (dogg Dogg) testa() {
   fmt.Println("testa")
}
func main() {
   var dog Dogg = Dogg{}

   //A2和B2的接口,创建的对象ia和ib只能调用自己的方法 不能调用ic方法
   var ia A2 = dog
   ia.testa()
   var ib B2 = dog
   ib.testb()

   //而ic由于继承了ia和ib的方法,所以ic都可以调用它们的方法
   var ic C2 = dog
   ic.testc()
   ic.testb()
   ic.testa()
}
/*
testa
testb
testc
testb
testa
*/

接口断言

检查接口类型变量的值是否实现了期望的接口,就是检查当前接口类型的值有没有实现指定的接口

把接口类型变量的值转换为其他类型或其他接口,go语言空interface{}可以保存任何类型的变量,当程序中需要使用变量的时候,需要把接口类型变量的值转换为具体类型,可以通过接口类型断言

其实很好理解,假如接口类型保存的值时数字,当前的值要参与数学运算,就必须转为int类型才可以参加运算,这就是利用接口断言来实现类型转换的例子

被断言的对象必须是接口类型,否则会报错

t:=i.(T)

t:=i.(T)

/*
断言成功,则t为T类型的接口值
断言失败则报错:panic
*/

v,ok :=i.(T)

v,ok :=i(T)
/*
断言成功,则v为T类型的接口值,ok为true
断言失败,则v为空值,ok为false
*/

type-switch

type switch
switch 接口变量.(type){
 	case 类型1:
 	//变量是类型1是的处理
 	case 类型2:
 	//变量是类型2是的处理
 	case nil:
 	//空接口进入此流程
 	default:
 	//变量不是所有case中列举的类型时的处理
}
package main

import "fmt"

//定义一个空接口i
type I interface {
}

func test08(i interface{}) {
   switch i.(type) { //默认为空
   case string: //判断是否为string类型 以此类推
      fmt.Println("string")
   case int:
      fmt.Println("int")
   case bool:
      fmt.Println("bool")
   case I:
      fmt.Println("I")
   case nil:
      fmt.Println("nil")
   }
}

func assertstring(i interface{}) {
   s := i.(string) //判断接口变量i是否为string类型
   fmt.Println(s)
}

func assertint(i interface{}) {
   s, ok := i.(int)
   if ok {
      fmt.Println("yes,接口变量是int类型", s)
   } else {
      fmt.Println("no,接口变量非int类型", s)
   }
}
func main() {
   a := "sss"
   b := 10
   c := true
   var i I
   test08(a)
   test08(b)
   test08(c)
   test08(i)

   assertstring("abc")
   //assertstring(12) 错误信息:panic: interface conversion: interface {} is int, not string
   assertint(12)
   assertint("qwe")

}
/*
string
int
bool
nil
abc
yes,接口变量是int类型 12
no,接口变量非int类型 0
*/

type别名

自定义类型

package main

import "fmt"

type Diyint int

类型别名

package main

import "fmt"
func main(){
    type myint =int
    var d myint = 30
}
package main

import "fmt"

// 通过type关键字的定义,Diyint是一种新的类型,它具有int的特性
// 它在函数外部定义,会影响到我们int类型的使用
type Diyint int

func main() {
   var a Diyint = 10
   var b int = 20
   //这里会报错fmt.Println(a+b),若想要计算使用,需要进行转换
   c := int(a) + b
   fmt.Println(c)

   // 在函数内部定义
   //myint 只会在代码中存在,编译完成时并不会有myint类型
   type myint = int
   var d myint = 30
   var e int = 40
   f := d + e
   fmt.Println(f)

}
/*
30
70
*/

标签:func,int,fmt,接口,Println,面向对象编程,Go,狂神,type
From: https://www.cnblogs.com/DuPengBG/p/17011217.html

相关文章

  • django中间件
    目录django中间件中间件简介自定义中间件(重要)中间件的顺序django中间件两个基本方法django中间件三个了解得方法基于django中间件的功能设计django中间件中间件简介1.流......
  • mongodb shell 统计相关命令
    mongodbshell统计相关命令1countdb.tbPosition.find().count(); #集合的总记录数db.tbPosition.find({Acnt_Id:437}).count() #符合条件的记录总数db.tbPosition.co......
  • CentOS7.2基于LAMP搭建WordPress,并自定义Logo和名称
    本次搭建LAMP+Wordpress环境如下MySQLphpWordpress_CN4.9ApacheCentOS7.2192.168.200.101、安装mariadb、php、httpd、wget2、测试php3、下载wordpress并配置4、网页......
  • golang写入influxdb2,共3种方式,小心有坑!
    ==事件背景==项目中需要接收设备上报的时序数据,写入到Influxdb中,在压力测试过程中发现服务器CPU占用的非常高,使用pprof解析了CPU占用的详细信息之后,发现Influxdb的AddFie......
  • mongodb副本集优先级设置
    在设置mongodb副本集时,Primary节点。second节点,仲裁节点,有可能资源配置(CPU或者内存)不均衡,所以要求某些节点不能成为Primary我们知道mongodb的设置: 除了仲裁节点,其它每一......
  • django查询中values_list(flat=True) 是什么意思?
    1.values()departments=models.Department.objects.filter(dpm_status=1).values('dnp__name')print(departments)# queryset中是一个个字典。“departments......
  • django 自带auth模块 实现 用户 注册、登录、验证、注销
    Auth模块只要是跟用户相关的登陆、注册、校验、修改密码、注销、验证用户是否登陆 内容详细Auth模块"""其实我们在创建好一个django项目之后直接执行数据库迁移......
  • 融云任杰:激活组织生命力 让听见炮火的人做决策 | TGO专访
    任杰,融云联合创始人兼首席科学家,TGO鲲鹏会(北京)学员;曾就职于微软和神州泰岳等公司,在微软两次获得全球杰出员工奖,曾负责中国联通搭建WAP网关、增值业务管理平台;在神州泰岳......
  • go简易tcp/udp连接测试工具
    packagemainimport( "fmt" "io" "log" "net" "os")funcshowBytes(bytes[]byte)string{ varstr[]byte for_,b:=rangebytes{ ifb>=33&&b......
  • Google Guava 工具类与 Kotlin 语言的设计
    GoogleGuava工具类与Kotlin语言的设计Guava工具类是什么Guavaisasuiteofcoreandexpandedlibrariesthatincludeutilityclasses,google'scollections,ioc......