遙想當(dāng)年學(xué)習(xí)C/C++時(shí),譚浩強(qiáng)老師那本紅皮的經(jīng)典教材《C語言程序設(shè)計(jì)》,前面大半本書都在講C語言的內(nèi)容,最后一兩個(gè)章節(jié)把C++的Class和面向?qū)ο蟮娜筇匦园岢鰜砹税锤担F(xiàn)在回憶起來當(dāng)時(shí)真的沒太學(xué)明白,只記得面向?qū)ο蟮奶匦允欠庋b胧卤、繼承唯绍、多態(tài)况芒,但也僅僅停留在能背出來绝骚,沒能理解什么真正的面向?qū)ο缶幊獭?/p>
真正理解面向?qū)ο缶幊蹋€得是感謝Java的出現(xiàn)止剖,Java寫的多了才開始對(duì)面向?qū)ο笥辛烁羁痰睦斫膺窗拢辉俚胶髞韺W(xué)習(xí)Python、C#待德、Swift橡庞、Kotlin才感覺如此輕松簡單。
今天來研究一下倉頡語言的class和struct法竞。
先說結(jié)論俯渤,在倉頡語言中,struct跟class的區(qū)別只有兩點(diǎn):
1略水、struct是值類型渊涝、class是引用類型
2厌处、struct不能繼承,class可以繼承
其他沒有什么區(qū)別缆娃。
倉頡spec還沒公開贯要,公開之后我可以給大家分析spec中關(guān)于struct和class的定義。
從實(shí)現(xiàn)層面來說,在編譯器前端,struct和class只是兩個(gè)關(guān)鍵字;在編譯器后端,class就是*struct尖飞。
一沮明、Struct
在倉頡語言的官方doc中琳袄,對(duì)struct的描述是這樣的:
“struct類型的定義以關(guān)鍵字struct開頭,后跟struct的名字碎紊,接著是定義在一對(duì)花括號(hào)中的struct定義體。struct定義體中可以定義一系列的成員變量、成員屬性(參見[屬性])、靜態(tài)初始化器、構(gòu)造函數(shù)和成員函數(shù)∑仔埃”
紙上得來終覺淺,我們還是一邊寫一邊理解吧。當(dāng)年大學(xué)C語言畢業(yè)設(shè)計(jì),相信大家都寫過C語言版本的“圖書管理系統(tǒng)”库继、“學(xué)生成績管理系統(tǒng)”之類的東西,我們就來寫一個(gè)倉頡版本的學(xué)生成績管理系統(tǒng)試試。
結(jié)合上一篇文章中的冒牌排序,稍作修改,實(shí)現(xiàn)一個(gè)總分排名的功能函數(shù):
實(shí)例化10位同學(xué)惋砂,排名玩一下罗标。
輸出結(jié)果:
student sort:[
(小明, 195.000000, A),
(小智, 192.000000, A),
(小櫻, 187.500000, A),
(小一, 171.000000, B),
(小桃, 157.000000, C),
(小楓, 140.000000, C),
(小鬼, 110.000000, E),
(小小, 107.000000, E),
(小衫, 103.000000, E),
(小旭, 93.000000, E)]
補(bǔ)考前 s1:
(小楓, 140.000000, C)
補(bǔ)考后 s1:
(小楓, 200.000000, A)
補(bǔ)考后原始 student[5]:
(小楓, 140.000000, C)
可以看到代碼321行谢澈,s1=student[5]拷貝后,對(duì)s1的修改沒有影響student[5],這就是值類型,相當(dāng)于321行完成了一次python中的深拷貝;從實(shí)現(xiàn)層面來說甲献,就是s1是新開辟的一塊內(nèi)存空間,跟student[5]完全指向兩個(gè)不同的內(nèi)存地址。
總結(jié)一下幾個(gè)關(guān)鍵點(diǎn):
- struct可以定義成員變量、靜態(tài)成員變量、成員函數(shù)输涕、靜態(tài)成員函數(shù)莱坎,即可以實(shí)現(xiàn)封裝
- struct可以定義名為init的構(gòu)造函數(shù)螟深,init構(gòu)造函數(shù)可以重載即定義多個(gè)
- struct可以定義與名稱相同的主構(gòu)造函數(shù)划栓,成員變量形參同時(shí)扮演定義成員變量和構(gòu)造函數(shù)參數(shù)的功能。例如,public Subject(var name: String, var grade: Float32) {} 在定義主構(gòu)造函數(shù)的時(shí)候同時(shí)申明了Subject的兩個(gè)成員變量:name和grade
- struct可以實(shí)現(xiàn)多態(tài)吱窝,即通過interface實(shí)現(xiàn)鲫惶,例如struct Student <: ToString
二、class
我們用class把剛才的student和subject重新實(shí)現(xiàn)一次啄清。
1、由于class中可以使用prop關(guān)鍵字浅缸,封裝性會(huì)看起來會(huì)更好一點(diǎn)蚌父;使用prop可以通過getter和setter方法將一個(gè)private的成員變量隱藏起來朝聋,使class之外完全不知道class內(nèi)部有什么成員變量
2、class可以使用繼承民宿,那么Student結(jié)構(gòu)完全可以拆解為Person和Student兩個(gè)class,并通過繼承復(fù)用父類的成員變量和方法
其他函數(shù)的實(shí)現(xiàn)沒有區(qū)別,我就不截圖了。
還是實(shí)例化10個(gè)student,然后排序、拷貝驗(yàn)證一下。
輸出結(jié)果:
[
(小明, 195.000000, A),
(小智, 192.000000, A),
(小櫻, 187.500000, A),
(小一, 171.000000, B),
(小桃, 157.000000, C),
(小楓, 140.000000, C),
(小鬼, 110.000000, E),
(小小, 107.000000, E),
(小衫, 103.000000, E),
(小旭, 93.000000, E)]
補(bǔ)考前 cs1:
(小楓, 140.000000, C)
補(bǔ)考后 cs1:
(小楓, 200.000000, A)
補(bǔ)考后原始 cstudent[5]:
(小楓, 200.000000, A)
可以看到代碼340行cs1對(duì)cstudent[5]拷貝之后秘豹,對(duì)cs1的修改最終影響到了cstudent[5]疲扎,就好比python中的淺拷貝管怠;實(shí)現(xiàn)層面上渤弛,cs1和cstudent[5]指向同一個(gè)內(nèi)存地址祝拯。
class其實(shí)跟其他高級(jí)語言的class沒什么區(qū)別,但凡寫過高級(jí)語言上手都能直接用她肯,當(dāng)然佳头,一些細(xì)節(jié)大家最好還是去讀一遍doc文檔。
最后晴氨,關(guān)于內(nèi)存的問題康嘉,大家如果只是寫高級(jí)語言可以不太理解,我下次再寫一篇關(guān)于C語言籽前、倉頡語言的內(nèi)存管理的文章亭珍。