最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Golang的繼承模擬實(shí)例

 更新時(shí)間:2021年06月29日 12:02:55   作者:戀喵大鯉魚  
這篇文章主要介紹了Go語言使用組合的方式實(shí)現(xiàn)多繼承的方法,實(shí)例分析了多繼承的原理與使用組合方式來實(shí)現(xiàn)多繼承的技巧,需要的朋友可以參考下,希望可以幫助到你

1.前言

面向?qū)ο缶幊痰娜筇匦裕悍庋b、繼承、多態(tài)。可見繼承是面向?qū)ο蟪绦蛟O(shè)計(jì)中一個(gè)重要的概念。Go 作為面向?qū)ο蟮木幊陶Z言,自然也支持繼承。

比較特殊的是 Go 實(shí)現(xiàn)繼承的方式與其他傳統(tǒng) OOP 語言所有不同,不像 C++ 有專門的繼承語法,或者像 Java 中有專門的關(guān)鍵字 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.嵌入式繼承機(jī)制

Go 使用匿名嵌套實(shí)現(xiàn)繼承。

我們用很容易理解的動(dòng)物-貓來舉例子。

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

首先,我們實(shí)現(xiàn)了一個(gè) Animal 的結(jié)構(gòu)體,代表動(dòng)物類。并聲明了 Name 字段,用于描述動(dòng)物的名字。

然后,實(shí)現(xiàn)了一個(gè)以 Animal 為 receiver 的 Eat 方法,來描述動(dòng)物進(jìn)食的行為。

最后,聲明了一個(gè) Cat 結(jié)構(gòu)體,組合了 Cat 字段。再實(shí)例化一個(gè)貓,調(diào)用Eat方法,可以看到會(huì)正常的輸出。

可以看到,Cat 結(jié)構(gòu)體本身沒有 Name 字段,也沒有去實(shí)現(xiàn) Eat() 方法。唯一有的就是匿名嵌套的方式繼承了 Animal 父類,至此,我們證明了 Go 通過匿名嵌套的方式實(shí)現(xiàn)了繼承。

上面是嵌入類型實(shí)例,同樣地也可以嵌入類型指針。

type Cat struct {
	*Animal
}
cat := &Cat{
	Animal: &Animal{
		Name: "cat",
	},
}

3.嵌入式繼承機(jī)制的的局限

相比于 C++ 和 Java, Go 的繼承機(jī)制的作用是非常有限的,因?yàn)闆]有抽象方法,有很多的設(shè)計(jì)方案可以在 C++ 和 Java 中輕松實(shí)現(xiàn),但是 Go 的繼承卻不能完成同樣的工作。

package main
import "fmt"
// Animal 動(dòng)物基類
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() 中調(diào)用的是基類 Animal.Speak() 方法,而不是 Dog.Speak()
}

運(yùn)行輸出:

Hachiko
my name is Hachiko and my gender is male
my name is Hachiko

上面的例子中,Dog 類型重寫了 Speak() 方法。然而如果父類型 Animal 有另外一個(gè)方法 Play() 調(diào)用 Speak() 方法,但是 Dog 沒有重寫 Play() 的時(shí)候,Dog 類型的 Speak() 方法則不會(huì)被調(diào)用,因?yàn)?Speak() 方法不是抽象方法,此時(shí)繼承無法實(shí)現(xiàn)多態(tài)。

4.使用接口封裝方法

為了解決上面的問題,我們應(yīng)該使用接口封裝方法,通過實(shí)現(xiàn)接口方法來實(shí)現(xiàn)多態(tài)。

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)
}

運(yùn)行輸出:

Hachiko
my name is Hachiko and my gender is male
my name is Hachiko and my gender is male

注意:Go 中某個(gè)類型需要實(shí)現(xiàn)接口中的所有方法才算作實(shí)現(xiàn)了接口。

5.小結(jié)

如果一個(gè) struct 嵌套了另一個(gè)匿名結(jié)構(gòu)體,那么這個(gè)結(jié)構(gòu)可以直接訪問匿名結(jié)構(gòu)體的屬性和方法,從而實(shí)現(xiàn)繼承。

如果一個(gè) struct 嵌套了另一個(gè)有名的結(jié)構(gòu)體,那么這個(gè)模式叫做組合。

如果一個(gè) struct 嵌套了多個(gè)匿名結(jié)構(gòu)體,那么這個(gè)結(jié)構(gòu)可以直接訪問多個(gè)匿名結(jié)構(gòu)體的屬性和方法,從而實(shí)現(xiàn)多重繼承。

本篇文章就到這里了,希望能幫助到你,也希望您能多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • Golang標(biāo)準(zhǔn)庫和外部庫的性能比較

    Golang標(biāo)準(zhǔn)庫和外部庫的性能比較

    這篇文章主要介紹Golang標(biāo)準(zhǔn)庫和外部庫的性能比較,下面文章講圍繞這兩點(diǎn)展開內(nèi)容,感興趣的小伙伴可以參考一下
    2021-10-10
  • Golang二進(jìn)制反匯編問題

    Golang二進(jìn)制反匯編問題

    這篇文章主要介紹了Golang二進(jìn)制反匯編問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • Golang使用Gin處理下載文件請求返回

    Golang使用Gin處理下載文件請求返回

    在Go語言中,使用Gin框架實(shí)現(xiàn)文件下載功能相對簡單,本文給大家展示一個(gè)簡單的示例,演示如何使用Gin來處理文件下載請求,文中通過代碼示例給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2024-01-01
  • Golang實(shí)現(xiàn)深拷貝reflect原理示例探究

    Golang實(shí)現(xiàn)深拷貝reflect原理示例探究

    這篇文章主要為大家介紹了Golang實(shí)現(xiàn)reflect深拷貝原理示例探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01
  • golang中常見的logrus日志庫

    golang中常見的logrus日志庫

    這篇文章主要介紹了golang中常見的logrus日志庫的相關(guān)資料,需要的朋友可以參考下
    2023-05-05
  • Go并發(fā)同步Mutex典型易錯(cuò)使用場景

    Go并發(fā)同步Mutex典型易錯(cuò)使用場景

    這篇文章主要為大家介紹了Go并發(fā)同步Mutex典型易錯(cuò)使用場景示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • Go設(shè)計(jì)模式之觀察者模式圖解

    Go設(shè)計(jì)模式之觀察者模式圖解

    觀察者模式是一種行為設(shè)計(jì)模式, 允許你定義一種訂閱機(jī)制, 可在對象事件發(fā)生時(shí)通知多個(gè) “觀察” 該對象的其他對象,下面這篇文章主要給大家介紹了關(guān)于圖解Go觀察者模式的相關(guān)資料,需要的朋友可以參考下
    2023-07-07
  • 淺談Golang中創(chuàng)建一個(gè)簡單的服務(wù)器的方法

    淺談Golang中創(chuàng)建一個(gè)簡單的服務(wù)器的方法

    這篇文章主要介紹了淺談Golang中創(chuàng)建一個(gè)簡單的服務(wù)器的方法,golang中的net/http包對網(wǎng)絡(luò)的支持非常好,這樣會(huì)讓我們比較容易的建立起一個(gè)相對簡單的服務(wù)器,有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-06-06
  • Golang使用CopyIn進(jìn)行批量創(chuàng)建的示例代碼

    Golang使用CopyIn進(jìn)行批量創(chuàng)建的示例代碼

    本文主要介紹了Golang使用CopyIn進(jìn)行批量創(chuàng)建的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • Go操作Kafka和Etcd方法詳解

    Go操作Kafka和Etcd方法詳解

    這篇文章主要為大家介紹了Go操作Kafka和Etcd方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09

最新評論

抚松县| 太谷县| 苍梧县| 鄢陵县| 林周县| 前郭尔| 凤阳县| 莒南县| 梨树县| 道孚县| 威信县| 余江县| 祁连县| 汝阳县| 广河县| 西林县| 耒阳市| 永吉县| 道真| 沈阳市| 巴彦淖尔市| 卢氏县| 永顺县| 天水市| 石渠县| 马关县| 丰县| 临颍县| 大石桥市| 沾益县| 噶尔县| 奎屯市| 西乌| 兰州市| 湟源县| 浦县| 剑川县| 峨眉山市| 安丘市| 林口县| 琼中|