一、go的结构体
type关键字可以声明一个新的数据类型,例如
type myint int
其中myint相当于int的一个别名,比如
var a myint=10
fmt.Printf("type of a=%T\n",a)
会打印出a的类型为myint类型
下面我来介绍一下结构体的定义,如下代码
func main() {
var book1 Book
book1.title = "Golang"
book1.auth = "yjy"
fmt.Printf("book1: %v\n", book1)
}
接下来我们试着做一些赋值打印吧~
//定义一个结构体
type Book struct {
title string
auth string
}
那么作为结构体,会不会也有值传递和引用传递的区别呢?那我们来浅试一下~
package main
import "fmt"
//定义一个结构体
type Book struct {
title string
auth string
}
//值传递
func changeBook(book Book) {
//传递一个book的副本
book.auth = "zqy"
}
//引用传递
func changeBook2(book *Book) {
//传递的是指针
book.auth = "zqy"
}
func main() {
var book1 Book
book1.title = "Golang"
book1.auth = "yjy"
fmt.Printf("book1: %v\n", book1)
changeBook(book1)
fmt.Printf("book1: %v\n", book1)
changeBook2(&book1)
fmt.Printf("book1: %v\n", book1)
}
最后打印结果如下图
编辑
二、类的表示与封装
特别的,还要说明一下大小写的区别。要知道在golang中大小写是不一样的。首字母大写表示对外public,其他包可以进行访问;首字母小写,其他包不可以访问,为私有属性。
下面我们来看一下如何定一个类,怎么通过setName让他的名字发生变化,看下面的代码~注意看带 “” 与不带 “” 的区别
package main
import "fmt"
//定义一个类,当前类大写首字母,其他包也可以访问
type Hero struct {
//属性名大写首字母,表示public其他包也可以用
Name string
Ad int
Level int
}
//方法名首字母小写,只能当前使用,其他包不能访问
func (this Hero) show(hero Hero) {
fmt.Printf("Hero: %v\n", hero)
}
func (this *Hero) show2() {
fmt.Println("Name=", this.Name)
fmt.Println("Ad=", this.Ad)
fmt.Println("Level=", this.Level)
}
func (this Hero) getName() string {
return this.Name
}
func (this *Hero) getName2() string {
return this.Name
}
func (this Hero) setName(newName string) {
//this是调用该方法的对象的一个拷贝
this.Name = newName
}
func (this *Hero) setName2(newName string) {
//this是调用该方法的对象的一个拷贝
this.Name = newName
}
func main() {
//创建一个对象
hero := Hero{Name: "yjy", Ad: 100, Level: 1}
hero.show(hero)
//注意看Name有没有变化
hero.setName("lisi") //没有变化
hero.show2()
hero.setName2("lisi") //会发生变化
hero.show2()
}
三、继承
子类继承父类,只需将父类名字放到子类定义中,更方便!!而定义子类对象的方法我也提供了两种,请看下面的代码
package main
import "fmt"
//定义一个父类,当前类大写首字母,其他包也可以访问
type Hero struct {
//属性名大写首字母,表示public其他包也可以用
Name string
Ad int
}
//定义一个子类
type Super struct {
Hero
level int
}
func (this *Hero) Eat() {
fmt.Println("Hero.Eat().....")
}
func (this *Hero) Walk() {
fmt.Println("Hero.Walk().....")
}
func (this *Super) Eat() {
fmt.Println("Super.Eat().....")
}
func (this *Super) flay() {
fmt.Println("Super.flay().....")
}
func main() {
//创建一个对象
hero := Hero{Name: "yjy", Ad: 100}
hero.Eat()
hero.Walk()
//定义一个子类对象
//super := Super{Hero{"yjy", 10}, 80}
//另一种定义方法
var super Super
super.Name="yjy"
super.Ad=10
super.level=80
super.flay()//调用子类方法
super.Walk()//调用父类方法
super.Eat()//调用子类方法
}
四、多态
基本要素:1.有接口(父类)(interface本质)是个指针
2.有子类实现接口中全部方法
3.父类类型的变量(指针)指向(引用)子类的具体的数据变量
下面我们来看一下代码
package main
import "fmt"
//interface本质是个指针
type Animal interface {
Sleep()
GetColor() string
GetType() string
}
//具体的类
type Cat struct {
Color string
}
//定义一个子类
type Dog struct {
Color string
}
func (this *Cat) Sleep() {
fmt.Println("Cat Sleep.....")
}
func (this *Cat) GetColor() string {
fmt.Println("Cat GetColor.....")
return this.Color
}
func (this *Cat) GetType() string {
fmt.Println("Cat type.....")
return "Cat"
}
func (this *Dog) Sleep() {
fmt.Println("Dog Sleep.....")
}
func (this *Dog) GetColor() string {
fmt.Println("Dog GetColor.....")
return this.Color
}
func (this *Dog) GetType() string {
fmt.Println("Dog type.....")
return "Dog"
}
func showtype(animal Animal) {
animal.Sleep()
fmt.Println(animal.GetType())
}
func main() {
var animal Animal //接口的数据类型,父类指针
animal = &Cat{"red"}
animal.Sleep() //调用cat的sleep方法,多态现象
animal = &Dog{"yellow"}
animal.Sleep()
cat := Cat{Color: "red"}
dog := Dog{Color: "yellow"}
showtype(&cat)
showtype(&dog)
}
既然说到interface,那我们再来了解一下interface吧~
interface是一个通用万能的类型,interface{}表示一个空接口。为什么说是万能的呢,哈哈,其实像那些基本的数据类型int、string、float、struct.......都实现了interface{},也就是说可以用interface{}类型引用任意的数据类型。下面看一下代码的实现吧~用到了断言机制
package main
import "fmt"
//interface{}万能能类型的测试
func myFun(arg interface{}) {
fmt.Println("myFun is called")
fmt.Println(arg)
//interface{}如何区分 此时引用的底层数据类型到底是什么?
//interface{}提供”类型断言“的机制
value, ok := arg.(string) //判断是否为string类型
if !ok {
fmt.Println("arg is not string")
} else {
fmt.Println("arg is a string type,value=", value)
}
}
//具体的类
type Cat struct {
Color string
}
func main() {
cat := Cat{Color: "red"}
myFun(cat)
myFun("abc")
myFun(10)
myFun(3.14)
}