溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

怎么理解Java面向?qū)ο笕筇匦?/h1>
發(fā)布時間:2021-12-21 16:07:56 來源:億速云 閱讀:92 作者:iii 欄目:編程語言

這篇文章主要講解了“怎么理解Java面向?qū)ο笕筇匦浴保闹械闹v解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“怎么理解Java面向?qū)ο笕筇匦浴卑桑?/p>

繼承

Java中的繼承只能單繼承,但是可以通過內(nèi)部類繼承其他類來實現(xiàn)多繼承。

public class Son extends Father{
public void go () {
System.out.println("son go");
}
public void eat () {
System.out.println("son eat");
}
public void sleep() {
System.out.println("zzzzzz");
}
public void cook() {
//匿名內(nèi)部類實現(xiàn)的多繼承
new Mother().cook();
//內(nèi)部類繼承第二個父類來實現(xiàn)多繼承
Mom mom = new Mom();
mom.cook();
}
private class Mom extends Mother {
@Override
public void cook() {
System.out.println("mom cook");
}
}
}

封裝

封裝主要是因為Java有訪問權(quán)限的控制。public > protected > package = default > private。封裝可以保護類中的信息,只提供想要被外界訪問的信息。

類的訪問范圍

A、public	包內(nèi)、包外,所有類中可見
B、protected	包內(nèi)所有類可見,包外有繼承關(guān)系的子類可見
(子類對象可調(diào)用)
C、(default)表示默認,不僅本類訪問,而且是同包可。
D、private	僅在同一類中可見

多態(tài)

多態(tài)一般可以分為兩種,一個是重寫overwrite,一個是重載override。

重寫是由于繼承關(guān)系中的子類有一個和父類同名同參數(shù)的方法,會覆蓋掉父類的方法。重載是因為一個同名方法可以傳入多個參數(shù)組合。
注意,同名方法如果參數(shù)相同,即使返回值不同也是不能同時存在的,編譯會出錯。
從jvm實現(xiàn)的角度來看,重寫又叫運行時多態(tài),編譯時看不出子類調(diào)用的是哪個方法,但是運行時操作數(shù)棧會先根據(jù)子類的引用去子類的類信息中查找方法,找不到的話再到父類的類信息中查找方法。
 而重載則是編譯時多態(tài),因為編譯期就可以確定傳入的參數(shù)組合,決定調(diào)用的具體方法是哪一個了。

向上轉(zhuǎn)型和向下轉(zhuǎn)型的解釋 :

public static void main(String[] args) {
        Son son = new Son();
        //首先先明確一點,轉(zhuǎn)型指的是左側(cè)引用的改變。
        //father引用類型是Father,指向Son實例,就是向上轉(zhuǎn)型,既可以使用子類的方法,也可以使用父類的方法。
        //向上轉(zhuǎn)型,此時運行father的方法
        Father father = son;
        father.smoke();
        //不能使用子類獨有的方法。
        // father.play();編譯會報錯
        father.drive();
        //Son類型的引用指向Father的實例,所以是向下轉(zhuǎn)型,不能使用子類非重寫的方法,可以使用父類的方法。
        //向下轉(zhuǎn)型,此時運行了son的方法
        Son son1 = (Son) father;
        //轉(zhuǎn)型后就是一個正常的Son實例
        son1.play();
        son1.drive();
        son1.smoke();
        ```
        //因為向下轉(zhuǎn)型之前必須先經(jīng)歷向上轉(zhuǎn)型。
        //        在向下轉(zhuǎn)型過程中,分為兩種情況:
        //
        //        情況一:如果父類引用的對象如果引用的是指向的子類對象,
        //        那么在向下轉(zhuǎn)型的過程中是安全的。也就是編譯是不會出錯誤的。
            //因為運行期Son實例確實有這些方法
            Father f1 = new Son();
            Son s1 = (Son) f1;
            s1.smoke();
            s1.drive();
            s1.play();
        //        情況二:如果父類引用的對象是父類本身,那么在向下轉(zhuǎn)型的過程中是不安全的,編譯不會出錯,
        //        但是運行時會出現(xiàn)java.lang.ClassCastException錯誤。它可以使用instanceof來避免出錯此類錯誤。
        //因為運行期Father實例并沒有這些方法。
            Father f2 = new Father();
            Son s2 = (Son) f2;
            s2.drive();
            s2.smoke();
            s2.play();
        //向下轉(zhuǎn)型和向上轉(zhuǎn)型的應(yīng)用,有些人覺得這個操作沒意義,其實可以用于方法參數(shù)中的類型聚合,然后具體操作再進行分解。
        //比如add方法用List引用類型作為參數(shù)傳入,傳入具體類時經(jīng)歷了向下轉(zhuǎn)型
        add(new LinkedList());
        add(new ArrayList());
        //總結(jié)
        //向上轉(zhuǎn)型和向下轉(zhuǎn)型都是針對引用的轉(zhuǎn)型,是編譯期進行的轉(zhuǎn)型,根據(jù)引用類型來判斷使用哪個方法
        //并且在傳入方法時會自動進行轉(zhuǎn)型(有需要的話)。運行期將引用指向?qū)嵗?,如果是不安全的轉(zhuǎn)型則會報錯。
        //若安全則繼續(xù)執(zhí)行方法。
    }
    public static void add(List list) {
        System.out.println(list);
        //在操作具體集合時又經(jīng)歷了向上轉(zhuǎn)型
//        ArrayList arr = (ArrayList) list;
//        LinkedList link = (LinkedList) list;
    }

總結(jié):
向上轉(zhuǎn)型和向下轉(zhuǎn)型都是針對引用的轉(zhuǎn)型,是編譯期進行的轉(zhuǎn)型,根據(jù)引用類型來判斷使用哪個方法。并且在傳入方法時會自動進行轉(zhuǎn)型(有需要的話)。運行期將引用指向?qū)嵗绻遣话踩霓D(zhuǎn)型則會報錯,若安全則繼續(xù)執(zhí)行方法。

編譯期的靜態(tài)分派:其實就是根據(jù)引用類型來調(diào)用對應(yīng)方法。

public static void main(String[] args) {
    Father father  = new Son();
    靜態(tài)分派 a= new 靜態(tài)分派();
    //編譯期確定引用類型為Father。
    //所以調(diào)用的是第一個方法。
    a.play(father);
    //向下轉(zhuǎn)型后,引用類型為Son,此時調(diào)用第二個方法。
    //所以,編譯期只確定了引用,運行期再進行實例化。
    a.play((Son)father);
    //當(dāng)沒有Son引用類型的方法時,會自動向上轉(zhuǎn)型調(diào)用第一個方法。
    a.smoke(father);
    //
    
}
public void smoke(Father father) {
    System.out.println("father smoke");
}
public void play (Father father) {
    System.out.println("father");
    //father.drive();
}
public void play (Son son) {
    System.out.println("son");
    //son.drive();
}

方法重載優(yōu)先級匹配

public static void main(String[] args) {
        方法重載優(yōu)先級匹配 a = new 方法重載優(yōu)先級匹配();
        //普通的重載一般就是同名方法不同參數(shù)。
        //這里我們來討論當(dāng)同名方法只有一個參數(shù)時的情況。
        //此時會調(diào)用char參數(shù)的方法。
        //當(dāng)沒有char參數(shù)的方法。會調(diào)用int類型的方法,如果沒有int就調(diào)用long
        //即存在一個調(diào)用順序char -> int -> long ->double -> ..。
        //當(dāng)沒有基本類型對應(yīng)的方法時,先自動裝箱,調(diào)用包裝類方法。
        //如果沒有包裝類方法,則調(diào)用包裝類實現(xiàn)的接口的方法。
        //最后再調(diào)用持有多個參數(shù)的char...方法。
        a.eat('a');
        a.eat('a','c','b');
    }
    public void eat(short i) {
        System.out.println("short");
    }
    public void eat(int i) {
        System.out.println("int");
    }
    public void eat(double i) {
        System.out.println("double");
    }
    public void eat(long i) {
        System.out.println("long");
    }
    public void eat(Character c) {
        System.out.println("Character");
    }
    public void eat(Comparable c) {
        System.out.println("Comparable");
    }
    public void eat(char ... c) {
        System.out.println(Arrays.toString(c));
        System.out.println("...");
    }
//    public void eat(char i) {
//        System.out.println("char");
//    }

感謝各位的閱讀,以上就是“怎么理解Java面向?qū)ο笕筇匦浴钡膬?nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對怎么理解Java面向?qū)ο笕筇匦赃@一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI