Java多型中過載方法引數分別為父類和子類時的疑惑
問題:
程式碼如下: class A { public String show(D obj){ return ("A and D"); } public String show(A obj){ return ("A and A"); } } class B extends A{ public String show(A obj){ return ("B and A"); } public String show(B obj){ return ("B and B"); } } class C extends B{} class D extends B{} public class MultiTest{ public static void main(String[] args){ A ab = new B(); B b = new B(); C c = new C(); System.out.println(ab.show(b)); System.out.println(ab.show(c)); } } 執行程式碼結果如下: B and A B and A 為什麼不是 B and B B and B
網友們給出的各種解答,挺好的
網友1、
A ab = new B(); 這裡ab的引用型別是A,但是它指向的記憶體是型別為B的一個例項 想對ab進行方法呼叫,你呼叫的方法都必須在 class A裡面有的才行(因為你的引用型別為A) 這裡 class A有show(A obj) show(D obj)著兩個方法 ab.show(b) 在class A中沒有找到型別匹配的方法,但是對b進行型別提升後,可以找到 show(A obj)方法,同理 ab.show(c)也是show(A obj)方法;但是ab記憶體地址指向一個型別為B記憶體空間,如果class B Override 了 class A的show(A obj)方法,則呼叫B的方法,反之,則呼叫A自己的方法 可以猜測 D d = new D(); ab.show(d)的結果是 A and D 如果註釋掉 class A的 show(A obj)方法, ab.show(b) ab.show(c)都會出錯。 這裡你只要記住,能呼叫那些方法,由引用型別決定,具體執行情況,由實際記憶體物件型別決定
網友2、
Override 是多型,由執行時實際類決定,所以呼叫的是B類的方法而不是A類的方法。
Overload 是由編譯器在編譯時決定的,因為 ab 的宣告型別為 A,所以會呼叫 show(A obj) 方法,編譯型別一致。
網友3、
Java 執行方法時,是動態匹配的,在執行時才會決定用哪個方法。A
ab = new B(); 你呼叫ab.show(b)時,會根據物件的型別A,去找方法,A中的show(A obj)匹配上,但是此方法在B中被覆蓋了,所以會呼叫B中的show(A obj)。
如果將程式碼改為:B ab = new B();,這個執行時:ab.show(b)會直接呼叫show(B obj);ab.show(c)會將c向上轉型一次,然後呼叫show(B obj)。
這樣的話最後的結果就會是:
B and B
B and B
總結:
java執行方法時,會根據物件的型別得到相應的方法,如果不存在編譯時會報錯,真正執行時,會動態去匹配,如果真正的物件是子類的話,且此方法在子類中被覆蓋的話,就會執行子類方法。
java型別匹配時,如果不能匹配的話就做向上型別轉換,轉換為父類,直到能夠匹配為止,若一直不能匹配在編譯時會報錯。
網友4、
這個涉及到了java的多型中的向上轉型,簡單來說,父類引用生成子類物件,那這個引用只能呼叫在父類中已經定義過的屬性和方法,而對子類自己新定義的屬性和方法則不能訪問。比如你這裡的A ab=new B();,ab是一個父類引用,之後執行ab.show(b),這時ab先從父類中查詢方法,與之匹配的只有show(A obj)方法,而且發現子類重寫了該方法,這時動態連結到子類的show(A
obj)方法。
假如你執行b.show(c),這裡,b中有show(A obj)方法和show(B obj)方法,繼承層次為C->B->A,根據過載的最近匹配原則,會呼叫show(B obj)方法。
自己在eclipse中寫了上面的程式碼,利用eclipse的自動提示方法呼叫功能,看了下對方法的提示,如下圖:
可以看到,提示的是A類中的兩個方法,而不是B類中的兩個方法,編譯的時候看的是引用型別,執行的時候呼叫的是實際型別。
相關推薦
Java多型中過載方法引數分別為父類和子類時的疑惑
問題: 程式碼如下: class A { public String show(D obj){ return ("A and D"); } public String show(A obj){
Java多型中的向上轉型和向下轉型
向上轉型:將一個父類的引用指向一個子類物件,稱為向上轉型,自動進行型別轉換 用法: Father f = new Son(); 向下轉型:子類引用指向父類引用的子類物件 通俗的說就是子類例項物件賦值給父類引用,然後父類引用又要賦值給子類引用,這個過程就是向下轉型
第十一章:Java多型中的引用型別轉換以及抽象類
引用型別轉換 1.向上型別轉換(隱式/自動型別轉換),是小型別到大型別的轉換。 2.向下型別轉換(強制型別轉換),是大型別到小型別 3.instanceof運算子,來解決引用物件的型別,避免型別轉換的安全性問題 抽象類 1.抽象類前使用abstract關鍵字修飾,
Java中父類和子類中的方法呼叫和引數傳遞探討
有這樣一段程式,看看它會輸出什麼結果 public class Test { public static void main(String [] args){ System.out.println(new B().getVa
深入理解系列之JAVA多型機制(過載/重寫)
多型(Polymorphism)按字面的意思就是“多種狀態”。在面嚮物件語言中,介面的多種不同的實現方式即為多型(來自百度百科)。所以,按照這個意思其實多型的“主題”是物件,但是實際在我們運用中我們常把“過載”和“重寫”稱之為“多型”其實這是不嚴謹的!過載
Java 多型中的強制型別轉換
目前多型情況下不能訪問子類特有的成員。 如果需要訪問子類特有的成員,那麼需要進行型別強制轉換. 基本資料型別的轉換 &nbs
java中父類和子類的關係和使用
在java中規定:一個父類可以有多個子類,但是一個子類只能有一個父類。子類可以通過extends關鍵字來繼承父類。做個比較通俗的比喻,就像一個父親可以有多個親孩子,但是一個孩子只能有一個親生父親。 1.繼承以及重寫:子類繼承父類是對父類屬性和方法的全面繼承,同時子類
Java繼承中父類和子類建構函式的問題
Java子類繼承父類在例項化時預設呼叫的是父類的無參建構函式,不論例項化時呼叫的是子類的有參還是無參建構函式,可以參考這篇Java子類例項化總是呼叫父類的無參構造方法 1、當父類沒有顯式定義構造方法時,編輯器會預設為此類新增一個隱式無參建構函式。此時子類可以有自己的無參和有參構造方法。 2、
Java中父類和子類丟擲異常的處理
(尊重勞動成果,轉載請註明出處:https://blog.csdn.net/qq_25827845/article/details/85109390冷血之心的部落格) 背景: 這篇部落格的靈感來自
關於java中父類和子類轉型的問題java.lang.ClassCastException
我們都知道,java是面向物件的語言,繼承是其一個很重要的特性,看下面這段程式碼:package my.java.test; class FatherClass { int fatherField; void fatherMethod() { Syst
Java中的繼承:父類和子類的關係
一、父類引用指向子類物件時 1、若子類覆蓋了某方法,則父類引用呼叫子類重新定義的新方法 2、若子類未覆蓋某方法,則父類引用呼叫父類本身的舊方法 3、若子類覆蓋了某屬性,但父類引用仍呼叫父類本身的舊屬性 4、若子類未覆蓋某屬性,則父類引用呼叫父類本身的舊屬性 5、父類引用不
C#中父類和子類之間相互轉換
mage all spa 分享 mic ack 子類 utl round 所用到的類文件:Person.cs:Student.cs:Teacher.cs:問題1:總結:1 父類不能直接強制轉換成子類2 只有父類對象指向子類,那麽父類是可以強制轉換成子類,如果父類對象沒有指向
Java——超類和子類物件之間的轉換
繼承是Java中常用的一項特性,通過繼承我們可以省去很多麻煩。 而Java中超類和子類物件之間的轉換則是很多新手的常遇見的難題,要是處理不好,恐怕會因為這個很特殊的問題導致一些潛在的危險,讓你整整一個晚上都在除錯程式以解決一個讓人抓狂的java.lang.ArrayStoreException異
“全棧2019”Java第五十八章:多型中方法返回型別可以是子類型別
難度 初級 學習時間 10分鐘 適合人群 零基礎 開發語言 Java 開發環境 JDK v11 IntelliJ IDEA v2018.3 文章原文連結 “全棧2019”Java第五十八章:多型中方法返回型別可以是子類型別 下一章 “全棧2019”Java第五十九章:抽
java中的繼承和多型以及過載和重寫
繼承(inheritance) 簡單的說,繼承就是在一個現有型別的基礎上,通過增加新的方法或者重定義已有方法(下面會講到,這種方式叫重寫)的方式,產生一個新的型別。繼承是面向物件的三個基本特徵--封裝、繼承、多型的其中之一,我們在使用JAVA時編寫的每一個
Java-多型、方法過載
什麼是多型、過載 1. 多型 對多型現象的理解 多型是面向物件的一個重要特徵。關於定義性的概念,相信網上有很多資料,不再多說。這裡說說我自己的理解。多型是指在執行期間,呼叫某個類物件的方法會有不同的行為。舉個最普遍的例子來說: 基類:Shape
3.Java面向物件程式設計OOA/OOP/OOD/OOAD()/UML類圖、函數語言程式設計Scala(JVM)---類與物件、封裝繼承多型、構造方法、覆寫/重寫/override
一、緒論 1.面向物件程式設計正規化(C++、Java、Go)------能進行現實生活的抽象。 每個物件都是一個類。類中包含屬性與方法。 OOA:面向物件分析 OOP:面向物件程式設計
【學習筆記】 唐大仕—Java程式設計 第5講 深入理解Java語言之5.2 多型及虛方法呼叫
/** * 多型及虛方法呼叫 * @author cnRicky * @date 2018.11.7 */ 多型 多型(Polymorphism)是指一個程式中相同的名字表示不同的含義的情況 多型有兩種情形 編譯時多型: *過載(Overload)(多個同名的不同方法) *如 p.sayH
java中,方法引數是基本型別和引用型別的區別
方法引數是基本型別時,傳遞的是值。 方法引數是引用型別時,傳遞的是記憶體地址值 當引數是基本型別時,在呼叫方法時將值傳遞到方法中,執行方法,執行結束方法退出,對原本main中定義的變數沒有任何操作(方法中沒有return)。即:此時只跟棧有關係,方法執行完之後(方法中沒有return),會彈棧。
“全棧2019”Java第五十七章:多型與構造方法詳解
難度 初級 學習時間 10分鐘 適合人群 零基礎 開發語言 Java 開發環境 JDK v11 IntelliJ IDEA v2018.3 文章原文連結 “全棧2019”Java第五十七章:多型與構造方法詳解 下一章 “全棧2019”Java第五十八章:多型中方法返回型