秒懂 go 语言的继承
对于go语言的继承,之前总是模模糊糊的分不清是什么。不知道如何通过何种方式来继承的。
然后我就开始对照着java的方式,用java实现继承,然后用go语言实现同样的继承。
java的继承
// 动物类
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岁了,特别喜欢睡觉
go 语言实现继承
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岁了,特别喜欢睡觉
是不是有点懂了,但是这只是最基础的封装,现在,在其他语言中,我们都知道,大多数都是以 interface 的方式来进行封装的。那么我们用 interface ,以一种高级的方式改造上面的例子如下:
使用接口的方式进行封装一个方法
package main
import (
"fmt"
"strconv"
)
type Animaler interface {
eat()
}
type Animal struct {
name string
age int
food string
}
// 实现 eat() 方法
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)
}
输出结果:
我叫咪咪, 我能睡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。
- 接口是一种类型。是一种特殊的类型,它规定了不同结构体有哪些相同的行为,只是制定标准,而不实现标准。就好比自来水厂只规定水龙头的半径大小,而不去考虑谁生产水龙头,生产水龙头的厂家不管用什么材料,只需要按照自来水厂的标准制定就好。
如果有不对的,希望各位大佬批评指正。感激不尽。
这是我本人的片面理解,仅仅是为了学习起来更快和更容易理解,而go语言本身是不推荐继承这个概念的,详细的可以参考这篇文章:studygolang.com/articles/17257
本作品采用《CC 协议》,转载必须注明作者和本文链接
图片挂了
@lovecn 没有啊,我这边正常显示 :flushed:
了解了
@shadowfpj 不胜荣幸 :grinning:
图片挂了,你是因为本地有缓存,去除缓存就可以看到无法访问了,或者换一个浏览器:
@Summer 好的,我重新修改下
Go语言继承说白了就是结构体内嵌
@Shenhi 是的,子类的结构体中将父类结构体的名字添加进去,就相当于实现了继承
go设计的思想就是用组合代替继承,这是个人的理解
@yourself 也没错,我没有试go里面是不是可以多继承。
@pureyb 推荐你看一下这篇文章希望对你有启发,我个人不建议用继承来理解go,容易让你掉入传统语言的思想里(不是说你理解的完全不对)。
https://studygolang.com/articles/17257
@yourself 感谢指正,因为或多或少学习的时候就想和其他语言做比较。所以就类似对比一下,看了你推荐的链接,获益匪浅。再次表示感谢 :+1: :+1: :+1:
@pureyb 推荐你可以去学习雨痕大佬的go语言学习笔记。
@yourself 感谢指引。
Golang多态的写法了解下哈哈哈,我也才学。多多交流。
@AaronGo