面向对象三大特征:封装、继承、多态。
方法
假设有两个方法,一个方法的接收者,是指针类型,一个方法的接收者是值类型,
那么:
对于值传递的变量和指针类型的变量,这两个方法的区别
如果这两个方法是为了实现一个接口,那么这两个方法都可以调用吗?
如果方法是嵌入到其他结构体中的,那么上面两种情况又是怎样的?
首先解决第一个问题:
对于值传递的变量和指针类型的变量,这两个方法的区别?
如下图测试示意:
很明显看出值传递和引用的区别。
封装
那么现在进入结构体的定义使用
定义
// 定义一个结构体
type Hero struct {Name string ``Age intSex int
}
上述就是定义了一个结构体,那怎么使用呢
package mainimport "fmt"type Person struct {Name stringAge int
}func main() {var p Personp.Name = "张三"var p2 Person = Person{"lisi", 15}p3 := Person{"wangwu", 15}fmt.Println(p, p2, p3)}
如图运行:
根据结构体来进一步构建类
其实类就是由结构体进一步绑定方法实现的。
package mainimport "fmt"// 定义一个结构体
type Hero struct {Name string ``Age intSex int
}func (hero Hero) SetName(name string) {//hero是调用方法的一个副本hero.Name = name}func (hero Hero) GetName() string {return hero.Name}func (hero Hero) Show() {fmt.Println("hero = ", hero)}func main() {var hero Hero = Hero{"赵六", 18, 1}hero.Show()hero.SetName("王五")hero.Show()}
明明在主函数进行了修改,但还是属性没有发送变化,是为什么呢?
其实是在给结构体挂上方法的时候,使用的是值传递
hero是一个方法的对象的一个副本
那么怎么解决呢?(使用指针)
package mainimport "fmt"// 定义一个结构体
type Hero struct {Name string ``Age intSex int
}func (hero *Hero) SetName(name string) {//hero是调用方法的一个副本hero.Name = name
}func (hero *Hero) GetName() string {return hero.Name
}func (hero *Hero) Show() {fmt.Println("hero = ", *hero)
}
func main() {var hero Hero = Hero{"赵六", 18, 1}hero.Show()hero.SetName("王五")hero.Show()}
如图:属性修改成功
注意:
类名首字母大写,标识其他包也能够访问
同理,属性、方法 大小写也是标识是否可以被外部访问
继承
语法就是在子类中添加上父类即可。如下代码:
package mainimport "fmt"type Person struct {Name stringAge int
}func (this *Person) Eat() {fmt.Println("Person Eat()...")
}func (this *Person) Walk() {fmt.Println("Person Walk()...")
}type SuperMan struct {Person //标识SuperMan继承了Person类的方法level int
}// 重定义父类的方法Eat()
func (this *SuperMan) Eat() {fmt.Println("SuperMan Eat()...")
}// 子类的新方法
func (this *SuperMan) Fly() {fmt.Println("SuperMan Fly()...")
}func main() {p := Person{"zhangsan", 18}p.Eat()p.Walk()s := SuperMan{Person{"张三", 18}, 0}s.Eat()s.Fly()s.Walk()var s1 SuperMans1.Name = "lisi"}
多态(依靠interface接口)
要素:
- 父类(接口)
- 子类(实现了父类的全部结构)
- 父类类型的变量(指针)指向子类的具体变量
package mainimport "fmt"type AnimalIF interface {Sleep() //让动物睡觉GetColor() string //获取动物颜色GetType() string //获取动物种类}// 具体的类
type Cat struct {//AnimalIF 继承接口没必要,只要定义方法实现就可以了,相当于继承了color string
}func (this *Cat) Sleep() {fmt.Println("小猫睡觉")
}func (this *Cat) GetColor() string {return this.color
}
func (this *Cat) GetType() string {return "Cat"
}type Dog struct {color string
}func (this *Dog) Sleep() {fmt.Println("小狗睡觉")
}
func (this *Dog) GetColor() string {return this.color
}
func (this *Dog) GetType() string {return "Dog"
}func showAnimal(animal AnimalIF) {animal.Sleep()fmt.Println(animal.GetColor())fmt.Println(animal.GetType())
}func main() {var cat AnimalIFcat = &Cat{"yellow"}var dog AnimalIF = &Dog{"blue"}showAnimal(cat)showAnimal(dog)
}