day08_面向?qū)ο骭繼承和多態(tài)

繼承

在此之前裂问,我要寫一個比較重要的一點遭顶,在JAVA核心教程和head of JAVA中都提到的张峰,單例設(shè)計模式,它的好處就是可以保證一個類在內(nèi)存中的對象唯一性棒旗。喘批。單例設(shè)計模式又可以分為懶漢式和餓漢式兩種,前者是在類加載到方法區(qū)的時候直接生成一個對象铣揉,餓漢式是在需要的時候再創(chuàng)建一個對象饶深。
所謂單例,就是這個類能且僅能初始化一個實例對象逛拱。怎么去實現(xiàn)呢敌厘?那就是阻止類以外的地方去創(chuàng)建對象,我在類中就直接創(chuàng)建好對象橘券。private構(gòu)造器就可以使得類外無法創(chuàng)建對象额湘,然后通過new 在本類中創(chuàng)建一個本類對象,定義一個公有的方法旁舰,將創(chuàng)建的對象返回锋华。

/**
懶漢式
@author Jason c
@version 1.0 
*/
class TestObject2
{
    private static TestObject2 instance;
    private TestObject2(){}
    public static TestObject2 getInstance()
    {
        if(instance==null)
            instance=new TestObject2();
        return instance;
        
    }
}
/*
餓漢式 
*/
class single2
{
    private static single2 instance=new single2();
    private single2() {}
    public static single2 getInstance()
    {
        return instance;
    }
}


如何實現(xiàn)繼承呢?

java提供了關(guān)鍵字:extends
格式:class 子類 extends 父類{}
好處:A.提高了代碼的復(fù)用性箭窜,提高了代碼的可維護性毯焕,讓類與類之間產(chǎn)生了關(guān)系,從而為多態(tài)提供了前提
類和類之前產(chǎn)生關(guān)系磺樱,其實也是繼承的弊端:類和類之前的耦合性增強了

開發(fā)的原則:低耦合纳猫,高內(nèi)聚
耦合:類與類之前的關(guān)系
內(nèi)聚:就是自己完成某件事的能力
java不支持多繼承,單支持多級繼承


繼承的注意事項:

子類只能繼承父類所有非私有的成員(成員變量和成員方法)
子類不能繼承父類的構(gòu)造方法竹捉,但是可以通過“super”關(guān)鍵字去訪問父類的構(gòu)造方法
不能因為部分功能而去繼承
什么時候使用繼承芜辕?
繼承其實體現(xiàn)的是一種關(guān)系,"is a"
只要符合這種邏輯關(guān)系块差,就可以使用繼承


繼承中侵续,成員變量之間的關(guān)系

在子類方法中訪問一個變量的查找順序
1.在子類方法的局部范圍找,有就使用
2.在子類的成員范圍找憨闰,有就使用
3.在父類的成員范圍找状蜗,有就使用
4.如果還找不到,報錯


this和super的區(qū)別?

分別是什么呢?
this代表本類對應(yīng)的引用鹉动。
super代表父類存儲空間的標(biāo)識(可以理解為父類引用,可以操作父類的成員)
怎么用呢?
A:調(diào)用成員變量
this.成員變量 調(diào)用本類的成員變量
super.成員變量 調(diào)用父類的成員變量
B:調(diào)用構(gòu)造方法
this(...) 調(diào)用本類的構(gòu)造方法
super(...) 調(diào)用父類的構(gòu)造方法
C:調(diào)用成員方法
this.成員方法 調(diào)用本類的成員方法
super.成員方法 調(diào)用父類的成員方法


繼承中構(gòu)造方法的關(guān)系

子類中所有的構(gòu)造方法都會訪問父類的無參構(gòu)造方法 因為子類會繼承父類的數(shù)據(jù)轧坎,可能還會使用父類的數(shù)據(jù),所以子類初始化之前泽示,一定要完成父類數(shù)據(jù)的初始化(默認(rèn)有一句super();)
子類每一個構(gòu)造方法的第一條語句默認(rèn)都是:super();
如果父類中只有一個有參的構(gòu)造方法缸血,在子類的構(gòu)造方法必須調(diào)用蜜氨,而且是子類的構(gòu)造方法第一句話必須是調(diào)用父類的有參構(gòu)造方法,否則編譯器會提示錯誤的属百。如果父類中有無參的構(gòu)造方法记劝,沒有寫的話,會自動調(diào)用的族扰,也就不會報錯厌丑。
**注意:super(...) 其中,"..."是需要載入的參數(shù)渔呵,即父類的有參構(gòu)造函數(shù)的參數(shù)值怒竿,并非參數(shù)的變量名。


如果父類沒有無參構(gòu)造方法扩氢,那么子類的構(gòu)造方法會出現(xiàn)什么現(xiàn)象呢?
報錯耕驰。
如何解決呢?
A:在父類中加一個無參構(gòu)造方法
B:通過使用super關(guān)鍵字去顯示的調(diào)用父類的帶參構(gòu)造方法
C:子類通過this去調(diào)用本類的其他構(gòu)造方法
子類中一定要有一個去訪問了父類的構(gòu)造方法,否則父類數(shù)據(jù)就沒有初始化录豺。

注意事項:

this(...)或者super(...)必須出現(xiàn)在第一條語句上朦肘。
如果不是放在第一條語句上,就可能對父類的數(shù)據(jù)進行了多次初始化双饥,所以必須放在第一條語句上媒抠。
子類初始化之前先初始化父類


方法重寫:子類中出現(xiàn)了和父類中方法聲明一模一樣的方法。

方法重載:
本類中出現(xiàn)的方法名一樣咏花,參數(shù)列表不同的方法趴生。與返回值無關(guān)。

子類對象調(diào)用方法的時候:
先找子類本身昏翰,再找父類苍匆。

方法重寫的應(yīng)用:

當(dāng)子類需要父類的功能,而功能主體子類有自己特有內(nèi)容時棚菊,可以重寫父類中的方法浸踩。
這樣,即沿襲了父類的功能统求,又定義了子類特有的內(nèi)容检碗。

案例:
A:定義一個手機類。
B:通過研究球订,我發(fā)明了一個新手機后裸,這個手機的作用是在打完電話后瑰钮,可以聽天氣預(yù)報冒滩。
按照我們基本的設(shè)計,我們把代碼給寫出來了浪谴。
但是呢?我們又發(fā)現(xiàn)新手機應(yīng)該是手機开睡,所以因苹,它應(yīng)該繼承自手機。
其實這個時候的設(shè)計篇恒,并不是最好的扶檐。
因為手機打電話功能,是手機本身就具備的最基本的功能胁艰。
所以款筑,我的新手機是不用在提供這個功能的。
但是腾么,這個時候奈梳,打電話功能就沒有了。這個不好解虱。
最終攘须,還是加上這個功能。由于它繼承了手機類殴泰,所以于宙,我們就直接使用父類的功能即可。
那么悍汛,如何使用父類的功能呢?通過super關(guān)鍵字調(diào)用

方法重寫的注意事項:

父類的私有方法不可以被重寫
子類重寫父類方法的時候捞魁,權(quán)限不可以更低,假如父類方法是public员凝,子類重寫后不可以變成private
類靜態(tài)方法署驻,子類也必須靜態(tài)方法

final關(guān)鍵字

繼承的代碼體現(xiàn)
由于繼承中方法有一個現(xiàn)象:方法重寫
所以,父類的功能健霹,就會被子類給覆蓋掉
有些時候旺上,我們不想讓子類去覆蓋掉父類的功能,只能讓他使用糖埋。
這個時候宣吱,針對這種情況,Java就提供了一個關(guān)鍵字:final
final:顧名思義瞳别,最終的意思征候,常見的是它可以修飾類
當(dāng)final修飾局部變量的時候,變量值無法改變
因此當(dāng)局部變量為一般數(shù)據(jù)類型的時候祟敛,局部變量==常量(值不變)
當(dāng)局部變量為引用數(shù)據(jù)類型的時候疤坝,局部變量==常量(值不變),此時的值是地址值馆铁,引用數(shù)據(jù)類型本身就是引用一個地址值跑揉,地址指向對象


多態(tài)

多態(tài)是同一個對象,在不同時刻表現(xiàn)出來的不同狀態(tài)历谍。

多態(tài)的前提:

    1.要有繼承關(guān)系
    2.要有方法重寫
            其實沒有也是可以的现拒,但是如果沒有這個就沒有意義。
    3.要有父類引用指向子類對象望侈。

多態(tài)中的成員訪問特點:

    1.成員變量
            編譯看左邊印蔬,運行看左邊。 
    2.構(gòu)造方法
            創(chuàng)建子類對象的時候脱衙,訪問父類的構(gòu)造方法侥猬,對父類的數(shù)據(jù)進行初始化。
    3.成員方法
            編譯看左邊捐韩,運行看右邊陵究。 (因為方法被覆蓋了)
    4.靜態(tài)方法
            編譯看左邊,運行看左邊奥帘。 
            靜態(tài)和類相關(guān)铜邮,算不上重寫,所以還是左邊的
    結(jié)論:由于成員方法存在方法重寫寨蹋,所以它運行看右邊松蒜,其他都是看左邊

    解析:
    先看代碼:
class Cat extends animals
{
    int num=1;  
}

class Dog extends animals
{
    int num=2;
    int num2=3; 
    public void Test ()
    {
        System.out.println(num);
    }
}
class animals
{
    int num=3;  
}
public class Test {
    public static void main(String[] args)
    {
        Dog D= new Dog();//創(chuàng)建一個Dog類的實例對象和Dog類的引用變量D,D指向Dog的實例對象
        animals a=D;//創(chuàng)建父類的引用變量a,指向引用變量D已旧;
        System.out.println(a.num2)//測試此時引用變量a是否可以獲得子類的成員變量num2
                a.Test();   //測試此時引用變量a是否可以獲得子類的方法Test()

    }
}

運行結(jié)果是秸苗,報錯,animals類中不含有Test()方法和成員變量num2运褪。
總結(jié)惊楼,當(dāng)引用變量為父類,指向子類的實例對象的時候秸讹,此時父類的引用變量就像是遙控器檀咙,上面的按鍵的功能只有父類擁有的,其他的“按不到”璃诀。


多態(tài)

那么弧可,如果此時我想使用子類的特有功能怎么辦?
Dog D2=a?
一定會報錯
因為向下轉(zhuǎn)型必須要通過強制類型轉(zhuǎn)換劣欢,因為其實它還是Dog對象棕诵,只是被聲明為animals類型。格式是Dog D2=(Dog)a凿将,這樣就不會報錯


一個非常經(jīng)典的多態(tài)小程序

多態(tài)的問題理解:
    class 孔子爹 {
        public int age = 40;
        
        public void teach() {
            System.out.println("講解JavaSE");
        }
    }
    
    class 孔子 extends 孔子爹 {
        public int age = 20;
        
        public void teach() {
            System.out.println("講解論語");
        }
        
        public void playGame() {
            System.out.println("英雄聯(lián)盟");
        }
    }
    
    //Java培訓(xùn)特別火,很多人來請孔子爹去講課校套,這一天孔子爹被請走了
    //但是還有人來請,就誓恋郑孔子在家笛匙,價格還挺高。孔子一想膳算,我是不是可以考慮去呢?
    //然后就穿上爹的衣服,帶上爹的眼睛弛作,粘上爹的胡子涕蜂。就開始裝爹
    //向上轉(zhuǎn)型
    孔子爹 k爹 = new 孔子();
    //到人家那里去了
    System.out.println(k爹.age); //40
    k爹.teach(); //講解論語
    //k爹.playGame(); //這是兒子才能做的
    
    
    //講完了,下班回家了
    //脫下爹的裝備映琳,換上自己的裝備
    //向下轉(zhuǎn)型
    孔子 k = (孔子) k爹; 
    System.out.println(k.age); //20
    k.teach(); //講解論語
    k.playGame(); //英雄聯(lián)盟

不管怎么樣机隙,程序的入口只能是main,因此在類加載后萨西,
應(yīng)從public static void main(String[] args)開始順序執(zhí)行有鹿。


多態(tài)的內(nèi)存圖解

多態(tài)對象變換的內(nèi)存圖解
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市谎脯,隨后出現(xiàn)的幾起案子葱跋,更是在濱河造成了極大的恐慌,老刑警劉巖源梭,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件娱俺,死亡現(xiàn)場離奇詭異,居然都是意外死亡废麻,警方通過查閱死者的電腦和手機荠卷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來烛愧,“玉大人油宜,你說我怎么就攤上這事×耍” “怎么了慎冤?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長沧卢。 經(jīng)常有香客問我粪薛,道長,這世上最難降的妖魔是什么搏恤? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任违寿,我火速辦了婚禮,結(jié)果婚禮上熟空,老公的妹妹穿的比我還像新娘藤巢。我一直安慰自己,他們只是感情好息罗,可當(dāng)我...
    茶點故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布掂咒。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪绍刮。 梳的紋絲不亂的頭發(fā)上温圆,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天,我揣著相機與錄音孩革,去河邊找鬼岁歉。 笑死,一個胖子當(dāng)著我的面吹牛膝蜈,可吹牛的內(nèi)容都是我干的锅移。 我是一名探鬼主播,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼饱搏,長吁一口氣:“原來是場噩夢啊……” “哼非剃!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起推沸,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤备绽,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后鬓催,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體疯坤,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年深浮,在試婚紗的時候發(fā)現(xiàn)自己被綠了压怠。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡飞苇,死狀恐怖菌瘫,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情布卡,我是刑警寧澤雨让,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站忿等,受9級特大地震影響栖忠,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜贸街,卻給世界環(huán)境...
    茶點故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一庵寞、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧薛匪,春花似錦捐川、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瘸右。三九已至,卻和暖如春岩齿,著一層夾襖步出監(jiān)牢的瞬間太颤,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工盹沈, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留龄章,地道東北人。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓襟诸,卻偏偏與公主長得像,于是被迫代替她去往敵國和親基协。 傳聞我的和親對象是個殘疾皇子歌亲,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,864評論 2 354

推薦閱讀更多精彩內(nèi)容