15.Golang的面向对象特性
1.封装
1.1.示例代码
obj1.go
package chapter12
import "fmt"
// 如果 类名 首字母大写,表示其他包也能够访问,否则只能当前包访问
type Hero struct {
// 如果类的属性 首字母 大写,表示该属性是对外能够访问的,否则的化只能够类的内部访问
Name string
Ad int
Level int
}
/*
func (hero Hero) Show() {
fmt.Println("Name = ", hero.Name)
fmt.Println("Ad = ", hero.Ad)
fmt.Println("Level = ", hero.Level)
}
func (hero Hero) getName() string {
return hero.Name
}
func (hero Hero) setName(newName string) {
// this 是调用该方法的对象一个副本(拷贝)
hero.Name = newName
}
*/
func (hero *Hero) Show() {
fmt.Println("Name = ", hero.Name)
fmt.Println("Ad = ", hero.Ad)
fmt.Println("Level = ", hero.Level)
}
func (hero *Hero) getName() string {
return hero.Name
}
func (hero *Hero) setName(newName string) {
// this 是调用该方法的对象一个副本(拷贝)
hero.Name = newName
}
func Run() {
// 创建一个对象
hero := Hero{
Name: "zhang3",
Ad: 100,
Level: 1,
}
hero.Show()
//修改对象名字
hero.setName("1i4")
hero.Show()
}
obj_test.go
package chapter12
import "testing"
func TestRun(t *testing.T) {
Run()
}
执行结果
=== RUN TestRun
Name = zhang3
Ad = 100
Level = 1
Name = 1i4
Ad = 100
Level = 1
--- PASS: TestRun (0.00s)
PASS
ok
1.2 小结

2.继承
2.1.示例代码
obj2.go
package chapter12
import "fmt"
// Human 定义 结构体
type Human struct {
name string
sex string
}
func (human *Human) Eat() {
fmt.Println("Human.Eat()...")
}
func (human *Human) Walk() {
fmt.Println("Human.Walk()...")
}
//=======================
// SuperMan 继承 Human
type SuperMan struct {
Human //SuperMan类继承了Human类的方法
level int
}
// 重定义父类的方式
func (superMan *SuperMan) Eat() {
fmt.Println("SuperMan.Eat()....")
}
//子类的新方法
func (superMan *SuperMan) Fly() {
fmt.Println("SuperMan.Fly()....")
}
func (superMan *SuperMan) print() {
fmt.Println("name = ", superMan.name)
fmt.Println("sex = ", superMan.sex)
fmt.Println("levle = ", superMan.level)
}
// main
func Run2() {
h := Human{
name: "zhang3",
sex: "female",
}
h.Eat()
h.Walk()
// 初始化一个子类对象
// 方式1
// s := SuperMan{
// Human: Human{
// name: "li4",
// sex: "man",
// },
// level: 10,
// }
// 方式2
var s SuperMan
s.name = "li4"
s.sex = "man"
s.level = 100
s.Eat() // 子类的eat
s.Walk() // 父类的walk
s.Fly() // 子类的fly
s.print()
}
执行结果
=== RUN TestRun2
Human.Eat()...
Human.Walk()...
SuperMan.Eat()....
Human.Walk()...
SuperMan.Fly()....
name = li4
sex = man
levle = 100
--- PASS: TestRun2 (0.00s)
PASS
ok
2.2.小结

3.多态
3.1.示例代码
obj3.go
package chapter12
import "fmt"
// 本质是一个指针
type AnimalIF interface {
Sleep()
GetColor() string // 获取动物的颜色
GetType() string // 获取动物的种类
}
// Cat 具体的类
type Cat struct {
color string // 猫的颜色func (cat *Cat) Sleep() {
}
func (dog *Cat) Sleep() {
fmt.Println("Cat is Sleep")
}
func (cat *Cat) GetColor() string {
return cat.color
}
func (cat *Cat) GetType() string {
return "Cat"
}
type Dog struct {
color string
}
func (dog *Dog) Sleep() {
fmt.Println("Dog is Sleep")
}
func (dog *Dog) GetColor() string {
return dog.color
}
func (dog *Dog) GetType() string {
return "Dog"
}
func showAnimal(animal AnimalIF) {
animal.Sleep() // 多态
fmt.Println("color = ", animal.GetColor())
fmt.Println("kind = ", animal.GetType())
}
func Run3() {
var animal AnimalIF // 接口的数据类型, 父类指针
animal = &Cat{"Green"}
animal.Sleep() // 调用的就是Cat的Sleep()方法
animal = &Dog{"Yellow"}
animal.Sleep() // 调用Dog的Sleep方法,多态现象
fmt.Println("-----------")
cat := Cat{"White"}
dog := Dog{"Black"}
showAnimal(&cat)
showAnimal(&dog)
}
执行结果
=== RUN TestRun3
Cat is Sleep
Dog is Sleep
-----------
Cat is Sleep
color = White
kind = Cat
Dog is Sleep
color = Black
kind = Dog
--- PASS: TestRun3 (0.00s)
PASS
ok
3.2.interface{}是万能数据类型
obj4.go
package chapter12
import (
"fmt"
)
// interface{}是万能数据类型
func myFunc(arg interface{}) {
fmt.Println("myFunc is called...")
fmt.Println(arg)
// interface{} 该如何区分,此时引用的底层数据类型到底是什么?
// 给 interface{} 提供 “类型断言” 的机制
value, ok := arg.(string)
if !ok {
fmt.Println("arg is not string type")
} else {
fmt.Println("arg is string type, value = ", value)
fmt.Printf("value type is %T\n", value)
}
}
type Book struct {
auth string
}
// main
func Run4() {
book := Book{auth: "Golang"}
myFunc(book)
myFunc(100)
myFunc("abc")
myFunc(3.14)
}
执行结果
=== RUN TestRun4
myFunc is called...
{Golang}
arg is not string type
myFunc is called...
100
arg is not string type
myFunc is called...
abc
arg is string type, value = abc
value type is string
myFunc is called...
3.14
arg is not string type
--- PASS: TestRun4 (0.00s)
PASS
ok
3.3.小结

4.总结
- 封装
- 结构体
- 类名、属性名,方法名 首字母大小,可以被其他包访问;小写,只能在本包内访问
- 继承
- 子类继承父类的属性,同样拥有父类的方法
- 子类可以重写父类的方法
- 子类可以新增方法
- 子类实例化方式有2种
- 方式1:
hero := Hero{
Name: "zhang3",
Ad: 100,
Level: 1,
} - 方式2:
var s SuperMan
s.name = "li4"
s.sex = "man"
s.level = 100
- 方式1:
- 多态
interface{}是指针类型;通用的万能类型interface{}提供类型断言的机制arg.(string)- 接口定义
type ${接口名} interface,其中type和interface是关键字 - 接口定义的方法,实现需要全部实现
func (dog *Cat) Sleep() { - 父类类型的变量(指针)指向(引用)子类的具体数据变量,
animal = &Cat{"Green"}

浙公网安备 33010602011771号