多态是什么 父类如何调用子类的方法(美团面试)
這道題是來自牛客網的一位小哥在2019的最后一天面試系統開發工程師的補招的一個面試題目, 在Java面試中,多態是一個被問到的頻率很高的一個概念。
面試官:什么是多態呢?
豬隊友:多種形態,氣體,液體,固體~
面試官:go out! now!
多態
多態(Polymorphism)按字面的意思就是“多種狀態”。在面向對象語言中,接口的多種不同的實現方式即為多態。引用Charlie Calverts對多態的描述——多態性是允許你將父對象設置成為一個或更多的他的子對象相等的技術,賦值之后,父對象就可以根據當前賦值給它的子對象的特性以不同的方式運作(摘自“Delphi4 編程技術內幕”)。簡單的說,就是一句話:允許將子類類型的指針賦值給父類類型的指針。多態性在Object Pascal和C++中都是通過虛函數實現的。
java多態
多態是同一個行為具有多個不同表現形式或形態的能力。
多態就是同一個接口,使用不同的實例而執行不同操作,如圖所示:
多態性是對象多種表現形式的體現。
現實中,比如我們按下 F1 鍵這個動作:
- 如果當前在 Flash 界面下彈出的就是 AS 3 的幫助文檔;
- 如果當前在 Word 下彈出的就是 Word 幫助;
- 在 Windows 下彈出的就是 Windows 幫助和支持。
同一個事件發生在不同的對象上會產生不同的結果。
多態的優點
多態存在的三個必要條件
- 繼承
- 重寫
- 父類引用指向子類對象
比如:
Animal a = new Cat();重寫父類方法:
//父類 public class Father{ //父類有一個打孩子方法public void hitChild(){} } //子類1 public class Son1 extends Father{ //重寫父類打孩子方法public void hitChild(){System.out.println("為什么打我?我做錯什么了!");} } //子類2 public class Son2 extends Father{ //重寫父類打孩子方法public void hitChild(){System.out.println("我知道錯了,別打了!");} } //子類3 public class Son3 extends Father{ //重寫父類打孩子方法public void hitChild(){System.out.println("我跑,你打不著!");} }//測試類 public class Test{public static void main(String args[]){Father father;father = new Son1();father.hitChild();father = new Son2();father.hitChild();father = new Son3();father.hitChild();} }Java里沒有多繼承,一個類之能有一個父類。而繼承的表現就是多態。一個父類可以有多個子類,而在子類里可以重寫父類的方法(例如方法print()),這樣每個子類里重寫的代碼不一樣,自然表現形式就不一樣。這樣用父類的變量去引用不同的子類,在調用這個相同的方法print()的時候得到的結果和表現形式就不一樣了,這就是多態,相同的消息(也就是調用相同的方法)會有不同的結果。
都調用了相同的方法,出現了不同的結果!這就是多態的表現!
如何理解向上轉型?
我定義了一個子類Cat,它繼承了Animal類,那么后者就是前者是父類。我可以通過
Cat c = new Cat();實例化一個Cat對象,這個不難理解。但當我這樣定義時:
Animal a = new Cat();這樣代表什么意思呢?
很簡單,它表示我定義了一個Animal類型的引用,指向新建的Cat類型的對象。由于Cat是繼承自它的父類Animal,所以Animal類型的引用是可以指向Cat類型的對象的。那么這樣做有什么意義呢?因為子類是對父類的一個改進和擴充,所以一般子類在功能上較父類更強大,屬性較父類更獨特:
定義一個父類類型的引用指向一個子類的對象既可以使用子類強大的功能,又可以抽取父類的共性。
所以,父類類型的引用可以調用父類中定義的所有屬性和方法,而對于子類中定義而父類中沒有的方法,它是無可奈何的;
對于父類中定義的方法,如果子類中重寫了該方法,那么父類類型的引用將會調用子類中的這個方法,這就是動態連接。
來我們舉個栗子:
class Father {public void func1(){func2();} public void func2(){System.out.println("AAA");} }class Child extends Father{public void func1(int i){System.out.println("BBB");} public void func2(){System.out.println("CCC");}}public class Test {public static void main(String[] args) {Father child = new Child();child.func1();//打印結果將會是什么?} }上面的程序是個很典型的多態的例子。子類Child繼承了父類Father,并重載了父類的func1()方法,重寫了父類的func2()方法。重載后的func1(int i)和func1()不再是同一個方法,由于父類中沒有func1(int i),那么,父類類型的引用child就不能調用func1(int i)方法。而子類重寫了func2()方法,那么父類類型的引用child在調用該方法時將會調用子類中重寫的func2()。
經過上面的分析我們可以知道打印的結果是什么呢? 很顯然,應該是"CCC"
多態有什么好處?
幾百本常用電子書免費領取:https://github.com/XiangLinPro/IT_book
If you cannot do great things, do small things in a great way.-- Napoleon Hill
如果你不能做偉大的事,那么就非凡地完成每件小事。
– 拿破侖.希爾
總結
以上是生活随笔為你收集整理的多态是什么 父类如何调用子类的方法(美团面试)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Shell环境变量深入了解
- 下一篇: 数组面试题-大力出奇迹?