Go語言沒有類怎么面向?qū)ο?/h1>

回顧

先回顧下面向?qū)ο蟮娜齻€基本特性:

  • 封裝
  • 繼承
  • 多態(tài)

Java作為面向?qū)ο蟮耐跽撸韵率纠昝赖恼宫F(xiàn)了面向?qū)ο蟮娜齻€基本特征。

uml.png
public class Main {
    public static void main(String[] args) {
        List<Payroll> all = new ArrayList<>();

        //員工類封裝了數(shù)據(jù)(姓名鸭津、年齡盒卸、性別)和行為(計算薪酬)
        //銷售員工和技術(shù)員工繼承自員工類较雕,都實(shí)現(xiàn)了計算薪酬的接口
        //機(jī)器不是員工搪缨,但實(shí)現(xiàn)了計算薪酬的接口食拜,也可以計算薪酬
        all.add(new SaleEmployee());
        all.add(new TechEmployee());
        all.add(new Machine());

        //多態(tài):不管是人還是機(jī)器,只要實(shí)現(xiàn)了Payroll接口副编,就都可以正確的計算出各自的薪酬
        for (Payroll payroll : all) {
            System.out.println(payroll.calcSalary());
        }
    }
}

那么Go語言呢负甸?我們一起來探索下Go語言的面向?qū)ο螅葟念惖姆庋b開始痹届。

封裝

員工薪酬示例中呻待,Java里的Employee類是這樣的:

public abstract class Employee implements Payroll {
    private String name;
    private String sex;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

這里暫時先關(guān)注員工類的三個屬性,Go里面它確實(shí)沒有類队腐,要表示上面的員工對象蚕捉,它是用struct的(和C很像):

type Employee struct {
    Name string
    Sex string
    Age int
}

看起來簡潔多了,注意到Go里面沒有private public的修飾符柴淘,它是用屬性的首個字母大小寫來區(qū)分private public迫淹,小寫字母開頭的是私有屬性,大寫字母開頭表示公開屬性为严。對象的實(shí)例化和使用對比:

//由于Employee是抽象類敛熬,不能實(shí)例化,直接用子類TechEmployee實(shí)例化
Employee tech = new TechEmployee();
tech.setName("lee");
System.out.println(tech.getName());
//這里的object.是包名第股,Employee放在object目錄下
tech := object.Employee{
    Name: "lee",
    Sex:  "male",
    Age:  20,
}
tech.Name = "bruce lee"
fmt.Println(tech.Name)

另外应民,struct中是沒有方法(行為)的,少了這個不是等于封裝特征缺了只腳嗎夕吻?當(dāng)然不是了瑞妇,Go語言里對應(yīng)面向?qū)ο罄锏某蓡T方法不是定義在struct里面,而是直接定義在struct外面梭冠,和struct平級,這里定義一個類似Java中的toString方法:

type Employee struct {
    Name string
    Sex  string
    Age  int
}

func (e *Employee) ToString() string {
    return "name=" + e.Name + ";sex=" + e.Sex + ";age=" + strconv.Itoa(e.Age)
}

這里(e *Employee)叫做方法的接收者改备,有點(diǎn)怪異控漠,我們可以這樣理解:

  1. Go里沒有this,要自己加個類似this的東西悬钳,用于指代方法對應(yīng)的實(shí)例盐捷,括號里前面的e相當(dāng)于this,當(dāng)然名字可以隨便取默勾。
  2. 方法定義和struct平級碉渡,如果不加個接收者定義,哪里知道這個方法屬于誰的呢母剥,括號里后面的類型表示這個方法屬性于誰的滞诺,這里可以用(e Employee)或(e *Employee)形导,區(qū)別是傳值還是傳指針,一般統(tǒng)一用后者习霹。

繼承

接下來繼承朵耕,先看看Java的:

public class TechEmployee extends Employee {
    private double salaryPerMonth;

    public double getSalaryPerMonth() {
        return salaryPerMonth;
    }

    public void setSalaryPerMonth(double salaryPerMonth) {
        this.salaryPerMonth = salaryPerMonth;
    }

    @Override
    public double calcSalary() {
        return salaryPerMonth;
    }
}

public class SaleEmployee extends Employee {
    private Double baseSalary;
    private Double extraRate;

    public Double getBaseSalary() {
        return baseSalary;
    }

    public void setBaseSalary(Double baseSalary) {
        this.baseSalary = baseSalary;
    }

    public Double getExtraRate() {
        return extraRate;
    }

    public void setExtraRate(Double extraRate) {
        this.extraRate = extraRate;
    }

    @Override
    public double calcSalary() {
        return baseSalary * (1 + extraRate);
    }
}

同樣,Go里面也沒有像Java中類似extend繼承的語法淋叶,Go是用了類似Java里組合的東西來讓語法看起來像繼承:

type TechEmployee struct {
    Employee
    SalaryPerMonth float32
}

type SaleEmployee struct {
    Employee
    BaseSalary float32
    ExtraRate  float32
}

對應(yīng)的實(shí)例化和使用:

//實(shí)例化時阎曹,是傳了個employee
tech := object.TechEmployee{
    Employee:       object.Employee{Name: "lee"},
    SalaryPerMonth: 10000,
}
//這里看起來像擁有了Employee的name屬性,可以設(shè)置和訪問
tech.Name = "bruce lee"
fmt.Println(tech.Name)

多態(tài)

關(guān)于多態(tài)煞檩,必須要提接口处嫌,終于Go里也是有接口的了:

public interface Payroll {
    double calcSalary();
}
type Payroll interface {
    CalcSalary() float32
}

接口的實(shí)現(xiàn):

public class Machine implements Payroll {
    @Override
    public double calcSalary() {
        return 0;
    }
}
type TechEmployee struct {
    Employee
    SalaryPerMonth float32
}

func (e *TechEmployee) CalcSalary() float32 {
    return e.SalaryPerMonth
}

type Machine struct {

}

func (e *Machine) CalcSalary() float32 {
    return 0
}

可以看出,Java里比較直觀斟湃,語法里直接寫著實(shí)現(xiàn)xxx接口熏迹,Go相比的話,沒那么直觀桐早,但更靈活癣缅,它沒有指定實(shí)現(xiàn)哪個接口,而是如果定義了一個相同名字和返回值的方法哄酝,就認(rèn)為是實(shí)現(xiàn)了對應(yīng)擁有這個方法的接口友存,這里假如接口有兩個方法,對應(yīng)也必須要兩個方法都有定義了陶衅,才認(rèn)為是實(shí)現(xiàn)了接口屡立。

最后,看一下集成使用的對比:

List<Payroll> all = new ArrayList<>();

//員工類封裝了數(shù)據(jù)(姓名搀军、年齡膨俐、性別)和行為(計算薪酬)
//銷售員工和技術(shù)員工繼承自員工類,都實(shí)現(xiàn)了計算薪酬的接口
//機(jī)器不是員工罩句,但實(shí)現(xiàn)了計算薪酬的接口焚刺,也可以計算薪酬
all.add(new SaleEmployee());
all.add(new TechEmployee());
all.add(new Machine());

//多態(tài):不管是人還是機(jī)器,只要實(shí)現(xiàn)了Payroll接口门烂,就都可以正確的計算出各自的薪酬
for (Payroll payroll : all) {
    System.out.println(payroll.calcSalary());
}
var all [3] object.Payroll

all[0] = &object.TechEmployee{
    Employee:       object.Employee{Name: "lee"},
    SalaryPerMonth: 10000,
}
all[1] = &object.SaleEmployee{
    Employee:   object.Employee{Name: "lee"},
    BaseSalary: 10000,
    ExtraRate:  0.1,
}
all[2] = &object.Machine{}

for _, item := range all {
    fmt.Println(item.CalcSalary())
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者

  • 序言:七十年代末乳愉,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子屯远,更是在濱河造成了極大的恐慌蔓姚,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件慨丐,死亡現(xiàn)場離奇詭異坡脐,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)房揭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進(jìn)店門备闲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來晌端,“玉大人,你說我怎么就攤上這事浅役≌端桑” “怎么了?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵觉既,是天一觀的道長惧盹。 經(jīng)常有香客問我,道長瞪讼,這世上最難降的妖魔是什么钧椰? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮符欠,結(jié)果婚禮上嫡霞,老公的妹妹穿的比我還像新娘。我一直安慰自己希柿,他們只是感情好诊沪,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著曾撤,像睡著了一般端姚。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上挤悉,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天渐裸,我揣著相機(jī)與錄音,去河邊找鬼装悲。 笑死昏鹃,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的诀诊。 我是一名探鬼主播洞渤,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼属瓣!你這毒婦竟也來了您宪?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤奠涌,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后磷杏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體溜畅,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年极祸,在試婚紗的時候發(fā)現(xiàn)自己被綠了慈格。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片怠晴。...
    茶點(diǎn)故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖浴捆,靈堂內(nèi)的尸體忽然破棺而出蒜田,到底是詐尸還是另有隱情,我是刑警寧澤选泻,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布冲粤,位于F島的核電站,受9級特大地震影響页眯,放射性物質(zhì)發(fā)生泄漏梯捕。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一窝撵、第九天 我趴在偏房一處隱蔽的房頂上張望傀顾。 院中可真熱鬧,春花似錦碌奉、人聲如沸短曾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嫉拐。三九已至,卻和暖如春隆豹,著一層夾襖步出監(jiān)牢的瞬間椭岩,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工璃赡, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留判哥,地道東北人。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓碉考,卻偏偏與公主長得像塌计,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子侯谁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評論 2 355