首先聲明下go 沒(méi)有繼承葱她,沒(méi)有繼承撩扒,沒(méi)有繼承,重要事情說(shuō)三遍吨些。但是他又能實(shí)現(xiàn)繼承搓谆,通過(guò)一個(gè)神奇的東西 - 結(jié)構(gòu)體。
那么抽象類的使用場(chǎng)景是什么呢豪墅?
定義了一組接口泉手,但又不想強(qiáng)迫每個(gè)實(shí)現(xiàn)類都必須實(shí)現(xiàn)所有的接口∨计鳎可以用abstract class定義一組方法體螃诅,甚至可以是空方法體啡氢,然后由子類選擇自己所感興趣的方法來(lái)覆蓋。
某些場(chǎng)合下术裸,只靠純粹的接口不能滿足類與類之間的協(xié)調(diào),還必需類中表示狀態(tài)的變量來(lái)區(qū)別不同的關(guān)系亭枷。abstract的中介作用可以很好地滿足這一點(diǎn)袭艺。
規(guī)范了一組相互協(xié)調(diào)的方法,其中一些方法是共同的叨粘,與狀態(tài)無(wú)關(guān)的猾编,可以共享的,無(wú)需子類分別實(shí)現(xiàn)升敲;而另一些方法卻需要各個(gè)子類根據(jù)自己特定的狀態(tài)來(lái)實(shí)現(xiàn)特定的功能
說(shuō)人話就是:規(guī)范了執(zhí)行方法答倡,想覆蓋就重寫,不想覆蓋就用父類的就好了
在這些情況下驴党,我們需要使用抽象類繼承瘪撇,來(lái)幫助我們寫出更優(yōu)雅的代碼「圩可是在 golang 中又沒(méi)有抽象類的概念倔既,哪有如何呢?
那不得不介紹一種通過(guò) struct 和 interface 來(lái)在 golang 中實(shí)現(xiàn)抽象類的方法鹏氧。
因?yàn)間o 里面沒(méi)有extends
abstract
這些關(guān)鍵字渤涌,那么先從大家所熟悉的主流語(yǔ)言java
來(lái)引入一段代碼
java實(shí)現(xiàn)抽象類
1.創(chuàng)建抽象父類
package abstractModel;
public abstract class CatAbstract {
public abstract void steeringWheel();
public void run(){
System.out.println("我是父類方法-run,大家一起跑起來(lái)~");
}
}
我創(chuàng)建了一個(gè)公共的方法run
或者換一種名字叫做默認(rèn)方法
另外創(chuàng)建一個(gè)抽象方法steeringWheel
把还,子類都需要實(shí)現(xiàn)的
2.創(chuàng)建2個(gè)子類
第一個(gè)aodi的
package abstractModel;
public class Audi extends CatAbstract{
@Override
public void steeringWheel() {
System.out.println("我是奧迪的方向盤");
}
}
第二個(gè)benchi的
package abstractModel;
public class Benz extends CatAbstract{
@Override
public void steeringWheel() {
System.out.println("我是奔馳的方向盤");
}
@Override
public void run() {
System.out.println("我奔馳nb 有自己的方式跑起來(lái)");
}
}
運(yùn)行如下
package abstractModel;
public class AbstractMain {
public static void main(String[] args) {
Audi audi = new Audi();
audi.steeringWheel();
audi.run();
System.out.println("-----華麗分界線----");
Benz benz = new Benz();
benz.steeringWheel();
benz.run();
}
}
只要重寫了父類那么就用子類的实蓬,沒(méi)實(shí)現(xiàn)就用父類的,抽象方法一定要在子類實(shí)現(xiàn)吊履。
好了安皱,現(xiàn)在咱們用go 來(lái)實(shí)現(xiàn)這段java代碼
Go 實(shí)現(xiàn)抽象類
先來(lái)實(shí)現(xiàn)第一個(gè)父類
package abstractClass
import "fmt"
type CatAbstract struct {
ICatAbstract
}
type ICatAbstract interface {
SteeringWheel()
Run1()
}
func (c *CatAbstract) Run1() {
fmt.Println("我是父類方法-run,大家一起跑起來(lái)~")
}
創(chuàng)建一個(gè)interface
里面同樣有2個(gè)方法率翅。這2個(gè)方法放到這里练俐,起子類可以都來(lái)實(shí)現(xiàn)它,假如有一個(gè)默認(rèn)的方法run1
冕臭,那咱就默認(rèn)把它給實(shí)現(xiàn)了腺晾,那么他就不是一個(gè)抽象方法了,其實(shí)go里面壓根就沒(méi)這個(gè)東西辜贵,咱們是為了實(shí)現(xiàn)它悯蝉,而臨時(shí)定義的名字叫做抽象方法,記住go里萬(wàn)物皆結(jié)構(gòu)體托慨,比php萬(wàn)物皆數(shù)據(jù)更強(qiáng)大(對(duì)go這種語(yǔ)言寫設(shè)計(jì)模式代碼鼻由,真的蛋疼)
創(chuàng)建2個(gè)子類
package abstractClass
import "fmt"
type Audi struct {
CatAbstract
}
func (a *Audi) SteeringWheel() {
fmt.Println("我是奧迪的方向盤")
}
定義的第一個(gè)類audi
咱們就實(shí)現(xiàn)一個(gè)”抽象方法“ SteeringWheel
在創(chuàng)建另一個(gè)benz
package abstractClass
import "fmt"
type Benz struct {
CatAbstract
}
func (b *Benz) SteeringWheel() {
fmt.Println("我是奔馳的方向盤")
}
func (b *Benz) Run1() {
fmt.Println("我奔馳nb 有自己的方式跑起來(lái)")
}
它就很聰明的實(shí)現(xiàn)了2個(gè)
看效果
package abstractClass
import (
"fmt"
"testing"
)
func TestAbstractClass(t *testing.T) {
audi := &Audi{}
audi.SteeringWheel()
audi.Run1()
fmt.Println("-----華麗分界線----")
benz := &Benz{}
benz.SteeringWheel()
benz.Run1()
}
到這里就結(jié)束了,go沒(méi)有繼承,萬(wàn)物皆結(jié)構(gòu)體蕉世,請(qǐng)不要用其他語(yǔ)言的編程思想來(lái)寫go蔼紧,不然就是對(duì)自己的折磨。
請(qǐng)記住go沒(méi)有繼承狠轻,萬(wàn)物皆結(jié)構(gòu)體
go 起來(lái)吧奸例!