Java基础以及与C++的一些对比
這兩天回憶一些Java基礎(chǔ),感覺(jué)自己很多地方都不是很牢固,也花費(fèi)在不少時(shí)間和不少流量在手機(jī)上查資料。
還是寫下來(lái)這些東西以免再忘記。
同時(shí)還是要記住多動(dòng)手,編程最重要的就是動(dòng)手敲啊,有想法有疑問(wèn)就要自己去實(shí)現(xiàn)去驗(yàn)證。
1. 訪問(wèn)控制
Java的默認(rèn)訪問(wèn)權(quán)限(包訪問(wèn)權(quán)限)跟C++中的友元很像其實(shí),都具有一定的特殊性。
同一個(gè)包中的類是可以任意訪問(wèn)其他類的非私有成員的,而如果繼承關(guān)系發(fā)生在同一個(gè)包中,子類繼承的所有非私有成員都是可見(jiàn)的。
但如果繼承不是發(fā)生在同一個(gè)包中則會(huì)有很大不同,通過(guò)繼承導(dǎo)入的包,子類只有繼承的保護(hù)和公有成員才是可見(jiàn)的。
導(dǎo)入的包只能導(dǎo)入該包內(nèi)的公有類和該公有類的公有成員,保護(hù)成員在子類中可見(jiàn),但即使在子類中也不能通過(guò)父類對(duì)象來(lái)訪問(wèn)保護(hù)成員,只能通過(guò)子類訪問(wèn)繼承后的保護(hù)成 員。
繼承發(fā)生的時(shí)候其實(shí)子類都會(huì)繼承父類的所有成員,不管是私有保護(hù)或者公有,只是訪問(wèn)修飾符不同導(dǎo)致了可見(jiàn)性的不同。
C++中的友元,允許訪問(wèn)友元類的所有變量,包括私有變量包括通過(guò)對(duì)象或?qū)ο笞鳛楹瘮?shù)引用參數(shù)訪問(wèn)。在子類中是不可以通過(guò)對(duì)象訪問(wèn)父類的保護(hù)成員的。只有公有成員可以通過(guò)對(duì)象或?qū)ο笾羔樤L問(wèn)。
C++有三種繼承方式,最常用的還是public繼承,而且Java直接閹割了其他的兩種繼承方式。
? ?關(guān)于類成員的protected權(quán)限,其實(shí)是很值得琢磨的我覺(jué)得。
介于private和public之間,在Java中,在同一個(gè)包內(nèi)發(fā)生的繼承就不說(shuō)了,除了非私有成員其他類(包括子類)都可以任意訪問(wèn),包括通過(guò)對(duì)象訪問(wèn),子類繼承的除非私有成員外也都具有可見(jiàn)性。和如果在不同包下的繼承,在子類中就沒(méi)有辦法通過(guò)父類對(duì)象訪問(wèn)protected成員,在這一點(diǎn)上和C++還是很像,C++中子類是沒(méi)有辦法通過(guò)父類對(duì)象訪問(wèn)父類的保護(hù)成員的。
?
?
關(guān)于訪問(wèn)控制,其實(shí)OOP思想的語(yǔ)言都大同小異,不管是Java,C++,還是C#。
2. 抽象類與接口
抽象類中可以沒(méi)有抽象方法,但具有抽象方法的類必須定義為抽象類,抽象類不能實(shí)例化。
接口中的變量自動(dòng)具有public static final屬性,接口中的方法自動(dòng)具有public abstract屬性,接口允許多繼承。
C++中含有純虛函數(shù)的類稱為虛基類,和Java中的接口比較像,但虛基類中的函數(shù)除了純虛函數(shù)都可以有自己的實(shí)現(xiàn),虛基類同樣不能實(shí)例化。純虛函數(shù)不能有自己的函數(shù)體,但是純虛析構(gòu)函數(shù)除外。
3. 重寫與重載
C++中用虛函數(shù)來(lái)實(shí)現(xiàn)多態(tài)機(jī)制,而Java中的類的方法都是隱式的虛函數(shù)。
重寫(覆蓋、override、overwrite)是子類和父類的變量名變量類型、方法名方法參數(shù)的類型個(gè)數(shù)順序完全一樣。
重載是函數(shù)名相同,參數(shù)類型、參數(shù)個(gè)數(shù)有一個(gè)不同,參數(shù)順序的差異可不可以構(gòu)成重載視情況而定,函數(shù)的返回值不同構(gòu)不成重載。
在子類中訪問(wèn)父類被覆蓋的成員變量或方法,Java用super,C#用base,C++用作用域運(yùn)算符::。
動(dòng)態(tài)綁定的時(shí)候如果訪問(wèn)成員變量的話,都是訪問(wèn)父類引用(Java)或父類指針(C++)指向的父類的成員變量,C++和Java皆如此。
動(dòng)態(tài)綁定的話只有存在重寫的情況才會(huì)調(diào)用子類的方法函數(shù),如果不存在重載就直接在父類中尋找,如果找不到就報(bào)錯(cuò)。
如下面的例子:輸出 ?”father“。
Java中可以有所謂的”跨類重載“,但是C++中卻不允許,具體可以參考這篇博文:http://blog.csdn.net/anialy/article/details/7621619。
而C++中肯定也有可以突破這種限制的方法,見(jiàn)這里:http://blog.csdn.net/autumn20080101/article/details/8514813。
關(guān)于C++的虛函數(shù)與重寫,我覺(jué)得這篇文章講的很好:C++的虛函數(shù)與重寫。
4. Java/C++中的hash_map/unordered_map的實(shí)現(xiàn)原理。
其實(shí)就是一個(gè)哈希函數(shù),配合數(shù)組和鏈表實(shí)現(xiàn),會(huì)存在數(shù)組的重新動(dòng)態(tài)分配的過(guò)程。
5. 對(duì)Java多態(tài)的再思考
首先子類會(huì)繼承父類的所有成員變量和方法,即使是父類中的private部分,這是Java和C++肯定沒(méi)錯(cuò)的地方。
從這個(gè)意義上來(lái)講,以前想過(guò)的對(duì)象初始化問(wèn)題,其實(shí)就相當(dāng)于“子類自己對(duì)象的初始化”,而外在表現(xiàn)形式上看起來(lái)像先父類后子類等等那些初始化順序。
然后就是多態(tài)是基于重寫的,實(shí)際上仔細(xì)想想,如果在子類中重寫父類方法的話,因?yàn)榭隙ㄒ呀?jīng)繼承父類的方法,所以相當(dāng)于在子類里面有兩個(gè)“一模一樣”的函數(shù),
但是,在面向?qū)ο蟮倪^(guò)程中,這是允許的,這叫做重寫(覆蓋,override,overwrite),繼承的父類的函數(shù)會(huì)被隱藏掉。
而正確調(diào)用對(duì)應(yīng)的函數(shù)無(wú)疑依賴于多態(tài)由機(jī)制原理上的實(shí)現(xiàn),看來(lái)了解C++的虛函數(shù)表等底層一點(diǎn)的知識(shí)還是極其有必要。
6. C++中的using聲明
using聲明用于將變量或函數(shù)引入某一個(gè)空間,使其由不可見(jiàn)變?yōu)榭梢?jiàn)狀態(tài)。
聯(lián)想到上面提到的子類重載繼承的父類的函數(shù),在C++中子類再想調(diào)用重載過(guò)的父類的函數(shù),就必須用using聲明將其引進(jìn)來(lái)。
而Java中,在子類中繼承的父類的函數(shù)即使被重載過(guò)還是可見(jiàn)的,只有在被重寫的情況下才會(huì)失去其可見(jiàn)性。
有點(diǎn)令人意外的是,在C++中,子類中,using聲明可以引入被重寫過(guò)的父類的函數(shù),雖然這樣做沒(méi)有任何卵用,這個(gè)父類的函數(shù)依舊是不可見(jiàn)的。
其實(shí)這是合乎理的做法,你既然已經(jīng)重寫了父類的函數(shù),就已經(jīng)視為你在子類的作用域中不再需要這個(gè)父類的這個(gè)函數(shù),所以即使你強(qiáng)行引入,依舊是不可見(jiàn)的。
需要注意的是,using聲明在哪個(gè)訪問(wèn)權(quán)限下會(huì)決定該變量或函數(shù)的訪問(wèn)權(quán)限問(wèn)題。
而且,C++11新標(biāo)準(zhǔn)下,引入了一個(gè)新的語(yǔ)法糖,姑且稱為“繼承的構(gòu)造函數(shù)”,當(dāng)然是加引號(hào)的。
用using聲明來(lái)在子類中引入父類中眾多的構(gòu)造函數(shù),相當(dāng)于實(shí)現(xiàn)“透?jìng)鳌?#xff0c;這個(gè)using聲明的主要作用是令編譯器產(chǎn)生子類的構(gòu)造函數(shù)代碼。
using用于父類的構(gòu)造函數(shù)還有很多和通常的using不同之處,比如不會(huì)改變?cè)L問(wèn)權(quán)限,比如不會(huì)引入默認(rèn)、拷貝、移動(dòng)構(gòu)造函數(shù)。
詳細(xì)的說(shuō)明和例子在C++ primer中。
個(gè)人感覺(jué)這就是一個(gè)很甜的語(yǔ)法糖。
7. Java中子類對(duì)基類的方法進(jìn)行重寫時(shí),不能具有比父類更嚴(yán)格的訪問(wèn)權(quán)限,而C++中卻無(wú)此規(guī)定。
轉(zhuǎn)載于:https://www.cnblogs.com/niuxichuan/p/5854761.html
超強(qiáng)干貨來(lái)襲 云風(fēng)專訪:近40年碼齡,通宵達(dá)旦的技術(shù)人生總結(jié)
以上是生活随笔為你收集整理的Java基础以及与C++的一些对比的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Linux_磁盘管理
- 下一篇: [svc]visio绘制模具