浏览 1414
扫码
Go的多态
go 是一种强类型的语言,每当我从java切换到go时总有些许的不适应,但是追求优雅,就不应该妥协。
go没有 implements, extends 关键字,所以习惯于 OOP 编程,或许一开始会有点无所适从的感觉。 但go作为一种优雅的语言, 给我们提供了另一种解决方案, 那就是鸭子类型:看起来像鸭子, 那么它就是鸭子.
go中的多态比java的隐匿得多,严格上说没有多态,但可以利用接口进行,对于都实现了同一接口的两种对象,可以进行类似地向上转型,并且在此时可以对方法进行多态路由分发,完全代码如下
package mainimport ("fmt")// Vehicle 是一个超级接口。是所有交通工具必须实现的接口// 实现这个接口需要实现两个方法,description(),medium()type Vehicle interface {description() stringmedium() string}// car 类型.type Car struct {doors int}// Boat 类型.type Boat struct {rudders intmasts int}//description ... Car 实现 Vehicle接口的description方法// Vehicle interface.func (c Car) description() string {return fmt.Sprintf("I am a car with %v door(s). I move on the %v.", c.doors, c.medium())}// medium... Car 实现 Vehicle接口的medium方法func (c Car) medium() string {return "road"}// description ... Boat 实现 Vehicle接口的description方法func (b Boat) description() string {return fmt.Sprintf("I am a boat with %v rudder(s) and %v mast(s). I ride on %v.", b.rudders, b.masts, b.medium())}// medium... Boat 实现 Vehicle接口的medium方法func (b Boat) medium() string {return "water"}// ride ... 注意接口既能是一个只类型,也可以是一个引用类型。// 我们使用值类型(`Vehicle`)而不使用引用类型(`*Vehicle`)。// 参看 @See http://openmymind.net/Things-I-Wish-Someone-Had-Told-Me-About-Go/func ride(vehicle Vehicle) {fmt.Println(fmt.Sprintf("Literal Vehicle: Value is %v. Type is %T.", vehicle, vehicle))fmt.Println(vehicle.description())fmt.Println(fmt.Sprintf("Did you notice that the vehicle rides on %v?", vehicle.medium()))}// checkType ... 类型检查func checkType(vehicle Vehicle) {test1, ok1 := vehicle.(*Car)fmt.Println(fmt.Sprintf("Is %v a *Car? %v.", test1, ok1))test2, ok2 := vehicle.(Car)fmt.Println(fmt.Sprintf("Is %v a Car? %v.", test2, ok2))test3, ok1 := vehicle.(*Boat)fmt.Println(fmt.Sprintf("Is %v a *Boat? %v.", test3, ok1))test4, ok2 := vehicle.(Boat)fmt.Println(fmt.Sprintf("Is %v a Boat? %v.", test4, ok2))test5, ok3 := vehicle.(Vehicle)fmt.Println(fmt.Sprintf("Is %v a Vehicle? %v.", test5, ok3))}// main ...func main() {// Using & returns a pointer to the struct value.car := &Car{doors: 4,}// Not using & returns the struct value.boat := Boat{rudders: 1,masts: 3,}fmt.Println("Ride in the car!")ride(car)fmt.Println()fmt.Println("Ride in the boat!")ride(boat)fmt.Println()fmt.Println("Check the type of the car.")checkType(car)fmt.Println()fmt.Println("Check the type of the boat.")checkType(boat)fmt.Println()}