对于 go 语言的继承,之前总是模模糊糊的分不清是什么。不知道如何通过何种方式来继承的。
然后我就开始对照着 java 的方式,用 java 实现继承,然后用 go 语言实现同样的继承。
java 的继承
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| class Animal { public String name; public String subject;
void eat(String food) { System.out.println(name + "喜欢吃:" + food + ",它属于:" + subject); } }
class Cat extends Animal{ public int age; void sleep() { System.out.println(name + "今年" + age + "岁了,特别喜欢睡觉"); } }
public class Test{ public static void main(String[] args){ Animal a = new Animal(); a.name = "动物"; a.subject = "动物科"; a.eat("肉");
Cat cat = new Cat(); cat.name = "咪咪"; cat.subject = "猫科"; cat.age = 1; cat.eat("鱼"); cat.sleep(); } }
|
1 2 3 4
| 输出结果入下: 动物喜欢吃:肉,它属于:动物科 咪咪喜欢吃:鱼,它属于:猫科 咪咪今年1岁了,特别喜欢睡觉
|
go 语言实现继承
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| package main
import ( "fmt" "strconv" )
type Animal struct { name string subject string }
func (a *Animal) eat(food string) { fmt.Println(a.name + "喜欢吃:" + food +",它属于:" + a.subject) }
type Cat struct { Animal age int }
func (c Cat) sleep() { fmt.Println(c.name + " 今年" + strconv.Itoa(c.age) + "岁了,特别喜欢睡觉") }
func main() { animal := Animal{name:"动物", subject:"动物科"} animal.eat("肉")
cat := Cat{Animal: Animal{name:"咪咪", subject:"猫科"},age:1} cat.eat("鱼") cat.sleep() }
|
1 2 3 4
| 输出结果: 动物喜欢吃:肉,它属于:动物科 咪咪喜欢吃:鱼,它属于:猫科 咪咪 今年1岁了,特别喜欢睡觉
|
是不是有点懂了,但是这只是最基础的封装,现在,在其他语言中,我们都知道,大多数都是以 interface 的方式来进行封装的。那么我们用 interface ,以一种高级的方式改造上面的例子如下:
使用接口的方式进行封装一个方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| package main
import ( "fmt" "strconv" )
type Animaler interface { eat() }
type Animal struct { name string age int food string }
func (animal Animal) eat() { fmt.Println(animal.name + "今年"+ strconv.Itoa(animal.age) +"岁了," + "喜欢吃" + animal.food) }
type Cat struct { Animal time int }
type Dog struct { Animal plays string }
func (cat Cat) sleep() { fmt.Println("我叫" + cat.name + ", 我能睡" + strconv.Itoa(cat.time) + "分钟" ) }
func (dog Dog) play() { fmt.Println("我叫" + dog.name + "我喜欢玩" + dog.plays) }
func testInterface(animaler Animaler) { animaler.eat() }
func main() { cat := Cat{Animal:Animal{name:"咪咪", age:2, food:"鱼"}, time: 8} cat.sleep() testInterface(cat)
dog := Dog{Animal:Animal{name:"大黄", age:2, food:"骨头"}, plays:"球球"} dog.play() testInterface(dog) }
|
输出结果:
1 2 3 4
| 我叫咪咪, 我能睡8分钟 咪咪今年2岁了,喜欢吃鱼 我叫大黄我喜欢玩球球 大黄今年2岁了,喜欢吃骨头
|
总结
通过如上的代码可以看到,
- 在 go 语言中,
type name struct{}
结构体 就相当于其他语言中的 class
类的概念。
- 在其他语言中,方法是直接写在在 类 里面的,而在 go 语言中,我们对于该结构体,如果存在方法,比如猫咪存在睡觉的方法那么是以
func (结构体名) 方法名{}
,即 func(c Cat) sleep{}
的方式来声明方法。
- 在 java 中, string + int = string,int 类型的值不需要类型转换,而在 go 语言中,string + int,如果想要一个字符串,则需要对 int 类型的值转换为 string 类型,然后才能拼接。
下面着这两句话一定要熟记
- 结构体解决的是基本数据类型不能满足我们日常需要的问题。再简单点理解就是一个结构体就是一个 json 类型的 object。
- 接口是一种类型。是一种特殊的类型,它规定了不同结构体有哪些相同的行为,只是制定标准,而不实现标准。就好比自来水厂只规定水龙头的半径大小,而不去考虑谁生产水龙头,生产水龙头的厂家不管用什么材料,只需要按照自来水厂的标准制定就好。