您好,登錄后才能下訂單哦!
這篇文章主要講解了“怎么理解Java面向對象三大特性”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“怎么理解Java面向對象三大特性”吧!
Java中的繼承只能單繼承,但是可以通過內部類繼承其他類來實現多繼承。
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() { //匿名內部類實現的多繼承 new Mother().cook(); //內部類繼承第二個父類來實現多繼承 Mom mom = new Mom(); mom.cook(); } private class Mom extends Mother { @Override public void cook() { System.out.println("mom cook"); } } }
封裝主要是因為Java有訪問權限的控制。public > protected > package = default > private。封裝可以保護類中的信息,只提供想要被外界訪問的信息。
類的訪問范圍
A、public 包內、包外,所有類中可見 B、protected 包內所有類可見,包外有繼承關系的子類可見 (子類對象可調用) C、(default)表示默認,不僅本類訪問,而且是同包可。 D、private 僅在同一類中可見
多態一般可以分為兩種,一個是重寫overwrite,一個是重載override。
重寫是由于繼承關系中的子類有一個和父類同名同參數的方法,會覆蓋掉父類的方法。重載是因為一個同名方法可以傳入多個參數組合。 注意,同名方法如果參數相同,即使返回值不同也是不能同時存在的,編譯會出錯。 從jvm實現的角度來看,重寫又叫運行時多態,編譯時看不出子類調用的是哪個方法,但是運行時操作數棧會先根據子類的引用去子類的類信息中查找方法,找不到的話再到父類的類信息中查找方法。
而重載則是編譯時多態,因為編譯期就可以確定傳入的參數組合,決定調用的具體方法是哪一個了。
public static void main(String[] args) { Son son = new Son(); //首先先明確一點,轉型指的是左側引用的改變。 //father引用類型是Father,指向Son實例,就是向上轉型,既可以使用子類的方法,也可以使用父類的方法。 //向上轉型,此時運行father的方法 Father father = son; father.smoke(); //不能使用子類獨有的方法。 // father.play();編譯會報錯 father.drive(); //Son類型的引用指向Father的實例,所以是向下轉型,不能使用子類非重寫的方法,可以使用父類的方法。 //向下轉型,此時運行了son的方法 Son son1 = (Son) father; //轉型后就是一個正常的Son實例 son1.play(); son1.drive(); son1.smoke(); ``` //因為向下轉型之前必須先經歷向上轉型。 // 在向下轉型過程中,分為兩種情況: // // 情況一:如果父類引用的對象如果引用的是指向的子類對象, // 那么在向下轉型的過程中是安全的。也就是編譯是不會出錯誤的。 //因為運行期Son實例確實有這些方法 Father f1 = new Son(); Son s1 = (Son) f1; s1.smoke(); s1.drive(); s1.play(); // 情況二:如果父類引用的對象是父類本身,那么在向下轉型的過程中是不安全的,編譯不會出錯, // 但是運行時會出現java.lang.ClassCastException錯誤。它可以使用instanceof來避免出錯此類錯誤。 //因為運行期Father實例并沒有這些方法。 Father f2 = new Father(); Son s2 = (Son) f2; s2.drive(); s2.smoke(); s2.play(); //向下轉型和向上轉型的應用,有些人覺得這個操作沒意義,其實可以用于方法參數中的類型聚合,然后具體操作再進行分解。 //比如add方法用List引用類型作為參數傳入,傳入具體類時經歷了向下轉型 add(new LinkedList()); add(new ArrayList()); //總結 //向上轉型和向下轉型都是針對引用的轉型,是編譯期進行的轉型,根據引用類型來判斷使用哪個方法 //并且在傳入方法時會自動進行轉型(有需要的話)。運行期將引用指向實例,如果是不安全的轉型則會報錯。 //若安全則繼續執行方法。 } public static void add(List list) { System.out.println(list); //在操作具體集合時又經歷了向上轉型 // ArrayList arr = (ArrayList) list; // LinkedList link = (LinkedList) list; }
總結:
向上轉型和向下轉型都是針對引用的轉型,是編譯期進行的轉型,根據引用類型來判斷使用哪個方法。并且在傳入方法時會自動進行轉型(有需要的話)。運行期將引用指向實例,如果是不安全的轉型則會報錯,若安全則繼續執行方法。
public static void main(String[] args) { Father father = new Son(); 靜態分派 a= new 靜態分派(); //編譯期確定引用類型為Father。 //所以調用的是第一個方法。 a.play(father); //向下轉型后,引用類型為Son,此時調用第二個方法。 //所以,編譯期只確定了引用,運行期再進行實例化。 a.play((Son)father); //當沒有Son引用類型的方法時,會自動向上轉型調用第一個方法。 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(); }
public static void main(String[] args) { 方法重載優先級匹配 a = new 方法重載優先級匹配(); //普通的重載一般就是同名方法不同參數。 //這里我們來討論當同名方法只有一個參數時的情況。 //此時會調用char參數的方法。 //當沒有char參數的方法。會調用int類型的方法,如果沒有int就調用long //即存在一個調用順序char -> int -> long ->double -> ..。 //當沒有基本類型對應的方法時,先自動裝箱,調用包裝類方法。 //如果沒有包裝類方法,則調用包裝類實現的接口的方法。 //最后再調用持有多個參數的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面向對象三大特性”的內容了,經過本文的學習后,相信大家對怎么理解Java面向對象三大特性這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。