Java多態(tài)到底都有啥好處
多態(tài)到底是啥,就是當子類繼承父類的方法時,對其繼承下來的方法按照自己的方式重新定義(覆蓋重寫)。
1.向上轉型。
之前繼承有提到過。父類引用指向子類對象。這時的引用只能調用子類覆蓋重寫了的方法,不能調用子類特有方法。自動轉換
public class Main { public static void main(String[]args) { Father f = new Son(); f.money(); } } class Father{ void money() { System.out.println("父類的錢"); } } class Son extends Father{ void money() { System.out.println("子類的錢"); } void SonPlay() { System.out.println("爸爸我能打游戲嗎?"); } }
運行結果:
假如我要該引用區(qū)調用子類特有的方法(不是覆蓋重寫)呢? 會報錯 (下面的向下轉型就是解決這個問題)
下面舉個例子
不同語言輸出"HelloWorld"
(1)父類為正常類
public class Language{ //編程語言類 void HelloWorld() { //輸出HelloWorld } }
public class CLanguage extends Language{ //C語言類繼承編程語言類 void HelloWorld() { //輸出HelloWorld System.out.println("printf(\"HelloWorld!\");"); } }
public class JavaLanguage extends Language{ //Java繼承編程語言類 void HelloWorld(){ System.out.println("System.out.println(\"HelloWorld!\")"); } }
提供一個函數調用
public class Test { public static void main(String[]args) { //inputHelloWorld(new CLanguage()); //inputHelloWorld(new JavaLanguage()); //或者 Language language; language = new CLanguage(); inputHelloWorld(language); language = new JavaLanguage(); inputHelloWorld(language); } public static void inputHelloWorld(Language language) { language.HelloWorld(); } }
在不改變函數的形參(父類)下,實參(子類)的改變不會讓程序報錯。也就是說,我只需要關心的是函數的形參是與Language類相關的類(本身或者子類對象)就行,而無需考慮傳入的實參到底是哪個子類對象。
運行結果:
假如父類是接口或者是抽象類呢?也可以
(2)父類為接口
假如父類真的就是為了提供某標準,或者父類無需實現內容等情況,可以考慮吧父類變成接口,接口也支持多態(tài)。
public class Test { public static void main(String[]args) { //inputHelloWorld(new CLanguage()); //inputHelloWorld(new JavaLanguage()); //或者 Language language; language = new CLanguage(); inputHelloWorld(language); language = new JavaLanguage(); inputHelloWorld(language); } public static void inputHelloWorld(Language language) { language.HelloWorld(); } } interface Language{ //編程語言類 public void HelloWorld() ; //輸出HelloWorld } class CLanguage implements Language{ //C語言類繼承編程語言類 public void HelloWorld() { //輸出HelloWorld System.out.println("printf(\"HelloWorld!\");"); } } class JavaLanguage implements Language{ public void HelloWorld(){ System.out.println("System.out.println(\"HelloWorld!\")"); } }
運行結果:
當然,抽象類作為父類也可以實現多態(tài)哦。
2.向下轉型。
把父類引用指向子類對象的引用在強轉為不同子類對象。 轉完之后的對象可以調用子類特有方法
(解決上述的調用子類的特有方法會報錯)
public class Main { public static void main(String[]args) { Father f = new Son(); //f.money(); Son s = (Son)f; s.SonPlay(); } } class Father{ void money() { System.out.println("父類的錢"); } } class Son extends Father{ void money() { System.out.println("子類的錢"); } void SonPlay() { System.out.println("爸爸我能打游戲嗎?"); } }
運行結果:
在舉上面的編程語言輸出HelloWorld例子,假如我要求inputLanguage方法對于傳入的實參中的子類對象進行判斷,假如傳入的對象是C語言類就輸出新增的特有的方法,Java類也是一樣
這里就有點像簡單工廠模式(實參是啥我new啥)了,這里是實參是啥,我強轉之后,我調用對應的方法。
public class CLanguage implements Language{ //C語言類繼承編程語言類 public void HelloWorld() { //輸出HelloWorld System.out.println("printf(\"HelloWorld!\");"); } public void CReadMe() { //新增C語言子類特有方法 System.out.println("我是C語言"); } }
public class JavaLanguage implements Language{ public void HelloWorld(){ System.out.println("System.out.println(\"HelloWorld!\")"); } public void JavaReadMe() {//新增Java子類特有方法 System.out.println("我是Java"); } }
修改inputHelloWorld函數
public class Test { public static void main(String[]args) { //inputHelloWorld(new CLanguage()); //inputHelloWorld(new JavaLanguage()); //或者 Language language; language = new CLanguage(); inputHelloWorld(language); language = new JavaLanguage(); inputHelloWorld(language); } public static void inputHelloWorld(Language language) { if(language instanceof CLanguage) { CLanguage clanguage = (CLanguage) language; clanguage.CReadMe(); }else if(language instanceof JavaLanguage) { JavaLanguage javalanguage = (JavaLanguage)language; javalanguage.JavaReadMe(); } language.HelloWorld(); } }
運行結果:
總得來說,多態(tài)可以使函數在其父類形參不變下,實參可以傳入多個不同的子類對象。
相關文章
java微信小程序步數encryptedData和開放數據解密的實現
這篇文章主要介紹了java微信小程序步數encryptedData和開放數據解密的實現,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-09-09java自定義ClassLoader加載指定的class文件操作
這篇文章主要介紹了java自定義ClassLoader加載指定的class文件操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-02-02