Golang的继承模拟实例
作者:恋喵大鲤鱼 发布时间:2024-05-08 10:23:14
1.前言
面向对象编程的三大特性:封装、继承、多态。可见继承是面向对象程序设计中一个重要的概念。Go 作为面向对象的编程语言,自然也支持继承。
比较特殊的是 Go 实现继承的方式与其他传统 OOP 语言所有不同,不像 C++ 有专门的继承语法,或者像 Java 中有专门的关键字 extends。
C++ 的继承:
// 基类
class Animal {
public:
void eat();
void sleep();
};
// 子类
class Dog : public Animal {
public:
void bark();
};
Java 的继承:
// 基类
public class Animal {
public void eat(){};
public void sleep(){};
}
// 子类
public class Dog extends Animal {
public void bark(){};
}
2.嵌入式继承机制
Go 使用匿名嵌套实现继承。
我们用很容易理解的动物-猫来举例子。
type Animal struct {
Name string
}
func (a *Animal) Eat() {
fmt.Printf("%v is eating", a.Name)
fmt.Println()
}
type Cat struct {
Animal
}
cat := &Cat{
Animal: Animal{
Name: "cat",
},
}
cat.Eat() // cat is eating
首先,我们实现了一个 Animal 的结构体,代表动物类。并声明了 Name 字段,用于描述动物的名字。
然后,实现了一个以 Animal 为 receiver 的 Eat 方法,来描述动物进食的行为。
最后,声明了一个 Cat 结构体,组合了 Cat 字段。再实例化一个猫,调用Eat方法,可以看到会正常的输出。
可以看到,Cat 结构体本身没有 Name 字段,也没有去实现 Eat() 方法。唯一有的就是匿名嵌套的方式继承了 Animal 父类,至此,我们证明了 Go 通过匿名嵌套的方式实现了继承。
上面是嵌入类型实例,同样地也可以嵌入类型指针。
type Cat struct {
*Animal
}
cat := &Cat{
Animal: &Animal{
Name: "cat",
},
}
3.嵌入式继承机制的的局限
相比于 C++ 和 Java, Go 的继承机制的作用是非常有限的,因为没有抽象方法,有很多的设计方案可以在 C++ 和 Java 中轻松实现,但是 Go 的继承却不能完成同样的工作。
package main
import "fmt"
// Animal 动物基类
type Animal struct {
name string
}
func (a *Animal) Play() {
fmt.Println(a.Speak())
}
func (a *Animal) Speak() string {
return fmt.Sprintf("my name is %v", a.name)
}
func (a *Animal) Name() string {
return a.name
}
// Dog 子类狗
type Dog struct {
Animal
Gender string
}
func (d *Dog) Speak() string {
return fmt.Sprintf("%v and my gender is %v", d.Animal.Speak(), d.Gender)
}
func main() {
d := Dog{
Animal: Animal{name: "Hachiko"},
Gender: "male",
}
fmt.Println(d.Name())
fmt.Println(d.Speak())
d.Play() // Play() 中调用的是基类 Animal.Speak() 方法,而不是 Dog.Speak()
}
运行输出:
Hachiko
my name is Hachiko and my gender is male
my name is Hachiko
上面的例子中,Dog 类型重写了 Speak() 方法。然而如果父类型 Animal 有另外一个方法 Play() 调用 Speak() 方法,但是 Dog 没有重写 Play() 的时候,Dog 类型的 Speak() 方法则不会被调用,因为 Speak() 方法不是抽象方法,此时继承无法实现多态。
4.使用接口封装方法
为了解决上面的问题,我们应该使用接口封装方法,通过实现接口方法来实现多态。
package main
import (
"fmt"
)
type Animal interface {
Name() string
Speak() string
Play()
}
type Dog struct {
name string
gender string
}
func (d *Dog) Play() {
fmt.Println(d.Speak())
}
func (d *Dog) Speak() string {
return fmt.Sprintf("my name is %v and my gender is %v", d.name, d.gender)
}
func (d *Dog) Name() string {
return d.name
}
func Play(a Animal) {
a.Play()
}
func main() {
d :=&Dog{"Hachiko", "male"}
fmt.Println(d.Name())
fmt.Println(d.Speak())
Play(d)
}
运行输出:
Hachiko
my name is Hachiko and my gender is male
my name is Hachiko and my gender is male
注意:Go 中某个类型需要实现接口中的所有方法才算作实现了接口。
5.小结
如果一个 struct 嵌套了另一个匿名结构体,那么这个结构可以直接访问匿名结构体的属性和方法,从而实现继承。
如果一个 struct 嵌套了另一个有名的结构体,那么这个模式叫做组合。
如果一个 struct 嵌套了多个匿名结构体,那么这个结构可以直接访问多个匿名结构体的属性和方法,从而实现多重继承。
本篇文章就到这里了,希望能帮助到你,也希望您能多多关注asp之家的更多内容!
来源:https://blog.csdn.net/K346K346/article/details/117914689


猜你喜欢
- 1.1 什么是Mysql多实例?简单的说,Mysql多实例就是在一台服务器上同时开启多个不同的服务端口(如 : 3306/3307/3308
- 本文实例为大家分享了vue实现计时器的具体代码,供大家参考,具体内容如下这里做的是点击按钮开始与结束倒计时的功能<div class=
- 前言Python 中的sys 模块极为基础而重要,它主要提供了一些给解释器使用(或由它维护)的变量,以及一些与解释器强交互的函数。本文将会频
- AIML全名为Artificial Intelligence Markup Language(人工智能标记语言),是一种创建自然语言软件代理
- #!/usr/bin/env python## Copyright 2009 Facebook## Licensed under the A
- 一.图像加法运算1.Numpy库加法其运算方法是:目标图像 = 图像1 + 图像2,运算结果进行取模运算。当像素值<=255时,结果为
- VUE 集成LODOP插件打印Lodop、C-Lodop使用说明及样例http://www.lodop.net/LodopDemo.html
- 图表是比干巴巴的表格更直观的表达,简洁、有力。工作中经常遇到的场景是,有一些数值需要定时的监控,比如服务器的连接数、活跃用户数、点击某个按钮
- 建议有js基础,了解jquery,thinkphp,废话不说多下面就上代码《————HTML————》//thinkphp循环显示把data
- 引用Nmap库实现扫描功能,本节课比较简单一看就会。编写环境:Python2.x编写:首先安装Nmap程序,并添加环境变量pip insta
- 前言在目标检测中,数据集常常使用labelimg标注,会生成xml文件。本文旨在根据xml标注文件来裁剪目标,以达到去除背景信息的目的。xm
- 今天网页调试的时候在线订单出现错误:Server 对象 错误 'ASP 0178
- mysql installer community 8.0.16.0安装图文教程,,供大家参考,具体内容如下一、下载mysql-instal
- kmp算法KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt同时发现,因此人们称它为克努特
- list1 和list2 两个list , 想要得到list1是不是包含 list2 (是不是其子集 )a = [1,2] b = [1,2
- Jenkins和项目在两台服务器上Jenkins的下载安装部署省略,可自行上官网。1.安装maven插件完成后,会出现“
- 1.使用nuget下载:Microsoft.Extensions.Configuration.JsonPomelo.EntityFramew
- goto语句在Go编程语言中的goto语句提供无条件跳转从跳转到标记声明的功能。注意:使用goto语句是高度劝阻的在任何编程语言,因为它使得
- 一、urllib库是什么?urllib库用于操作网页 URL,并对网页的内容进行抓取处理urllib包 包含以下几个模块:urllib.re
- 题目:给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。示例:示例 1:输入: “abcabcbb”输出: 3解释: 因为无重