zoukankan      html  css  js  c++  java
  • go语言学习(五)——面向对象编程

    主要讲的是“类”和接口&和其他传统语言不一样的地方挺多的,断断续续看了好几天

    下面是我的练习代码

    // GoStudy0219 project main.go
    /*
    go语言学习——面向对象编程(1)
    go中类型的值语义和引用语义
    结构体(类)的定义和初始化
    */
    package main
    
    import (
    	"fmt"
    )
    
    func main() {
    	//几种“类”的初始化
    	v1 := &character{"Tom", 100, 10, 100} //这样定义出来的v1实际上时“类”的地址
    
    	v2 := new(character) //	等价于v4:=&character{}
    	v2.name = "Judy"
    	v2.hp = 50
    	v2.magic = 150
    	v2.attack = 30
    
    	v3 := &character{name: "Jim", hp: 150} //注意是花括号
    	v3.magic = 30
    	v3.attack = 20
    
    	fmt.Println(v1)
    	fmt.Println(v2)
    	fmt.Println(v3)
    	fmt.Println("*********************")
    
    	//使用类的函数
    	v1.addHp(600)
    	fmt.Println(v1)
    	fmt.Println(v1.hpIsLessThan(*v2))
    	fmt.Println(v2)
    	fmt.Println("*********************")
    
    	//其他类型
    	var v5 Age = 100
    	fmt.Println(v5)
    
    	v5.add(10)
    	fmt.Println(v5)
    
    	v5.errorAdd(10)
    	fmt.Println(v5)
    	fmt.Println("*********************")
    
    	//值语义和引用语义
    	//基本数据类型int,float之类的时值语义
    	//数组和切片是值语义
    	//map,channel和interface是引用语义
    
    }
    
    type Age int
    
    func (this *Age) add(target Age) {
    	*this += target
    }
    
    func (this Age) errorAdd(target Age) {
    	this += target
    }
    
    //结构体(与其他语言中的类地位相同)
    type character struct {
    	name   string
    	hp     float32
    	attack float32
    	magic  float32
    }
    
    func (this character) hpIsLessThan(target character) bool { //this character 不会改变this
    	target.attack = 66
    	return this.hp < target.hp
    }
    
    func (this *character) addHp(value float32) { //this *character 会改变this
    	this.hp += value
    }
    

     

    // GoStudy0223 project main.go
    /*
    go语言学习——面向对象编程(2)
    匿名组合
    可访问性
    */
    
    package main
    
    import (
    	"fmt"
    )
    
    func main() {
    	fmt.Println("Hello World!")
    
    	var stu *student = &student{1001, *&person{"Tom", 10, true}}
    	fmt.Println(stu)
    	stu.greet()           //匿名组合,能直接调用匿名的函数的方法
    	fmt.Println(stu.name) //匿名组合能够直接调用匿名函数的属性
    	stu.walk()            //多态重载的实现
    
    	var tea *teacher = &teacher{55, "Judy", *&person{"Tom", 10, false}}
    	fmt.Println(tea.name)
    }
    
    type person struct {
    	name  string
    	age   int
    	isMan bool
    }
    
    func (this *person) greet() {
    	fmt.Println("hello")
    }
    
    func (this *person) walk() {
    	fmt.Println("walk slow")
    }
    
    type student struct {
    	studentId int
    	person    //匿名组合
    }
    
    func (this *student) walk() { //相当于多态重载,外部调用walk时不再执行匿名函数中的walk函数
    	this.person.walk() //根据需求,实现了“基类”的函数,
    	fmt.Println("walk quick")
    }
    
    type teacher struct {
    	teacherId int
    	name      string //person 里面的name相当于被隐藏了,外部调用teacher.name的时候,person里面的name并不会起作用
    	person
    }
    
    /*
    匿名组合相当于用类型名称(去掉包名部分)作为成员变量的名字,
    因此,一个类型中如果同时有类似于person和xxx.person的时候可能会报错,因此要避免这种情况
    */
    
    /*
    首字母大写表示包外可访问,首字母小写,表示包外不能访问。
    同一包内,不论首字母是大写还是小写都是能访问的
    */
    

     

    // GoStudy0224 project main.go
    /*
    go语言学习——面向对象编程(3)
    接口
    */
    package main
    
    import (
    	"fmt"
    )
    
    func main() {
    	fmt.Println("Hello World!")
    
    	var per = &Person{"Tom", 50}
    	fmt.Println(per)
    
    	//接口的赋值
    	//用对象赋值
    	var v1 IAdd = per //这里传入的实际上是类型的地址
    	v1.Add(10)
    	fmt.Println(per)
    	//用接口赋值
    	var v2 IPerson = per
    	var v3 IWalk = v2 //函数“全”的接口可以像函数“少”的接口赋值;如果几个接口中函数相同,则这几个接口可以相互转换
    	v3.Walk()
    
    	if v4, ok := v2.(IRead); ok { //检测,接口v2能不能转换成IRead接口
    		v4.Read()
    	}
    
    	if v5, ok := v2.(*Person); ok { //检测,接口v2指向的对象类型是不是Person
    		fmt.Println(v5)
    	}
    
    	var v6 interface{} = per //interface{}是any类型,空接口
    	switch v7 := v6.(type) { //检测接口指向对象的类型
    	case int:
    		fmt.Println(v7, "int")
    	default:
    		fmt.Println(v7, "other")
    	}
    
    	var v8 IPerson2 = per
    	v8.Read()
    
    }
    
    type Person struct {
    	name string
    	age  int
    }
    
    func (this *Person) Add(value int) {
    	this.age += value
    }
    
    func (this *Person) Walk() {
    	fmt.Println("walk")
    }
    
    func (this *Person) Speak() {
    	fmt.Println("speak")
    }
    
    func (this *Person) Read() {
    	fmt.Println("read")
    }
    
    //定义接口
    type IWalk interface {
    	Walk() //定义接口函数,省略func关键字
    }
    
    type IRead interface {
    	Read()
    }
    
    type ISpeak interface {
    	Speak()
    }
    
    type IAdd interface {
    	Add(value int)
    }
    
    type IPerson interface {
    	Walk()
    	Read()
    	Speak()
    }
    
    type IPerson2 interface { //接口的组合,等同于上一个接口的写法
    	ISpeak
    	IRead
    	IWalk
    }
    
    /*传统语言的接口是一种契约,使用接口的类必须实现接口的所有方法,不同命名空间下的同名接口也被视为两个不同的接口
    eg. C# java等需要考虑定义什么接口,在哪个类里面实现接口
    go语言中,并不需要考虑上面的问题
    */
    
  • 相关阅读:
    Android服务之bindService源代码分析
    [iOS 高级] iOS远程推送与本地推送大致流程
    redis集群
    面试你之前,我希望在简历上看到这些!
    解决安卓出现导入第三方包反复的错误
    【PA2012】【BZOJ4289】Tax
    Spark jdbc postgresql数据库连接和写入操作源代码解读
    Java中hashcode的理解
    CvArr、Mat、CvMat、IplImage、BYTE转换
    CSDN日报20170413 ——《天天写业务代码的那些年,我们是怎样成长过来的》
  • 原文地址:https://www.cnblogs.com/singledigit/p/6387637.html
Copyright © 2011-2022 走看看