深入淺出探究Java多態(tài)的實現(xiàn)和應(yīng)用
多態(tài)是指同一操作作用于不同的對象上,能產(chǎn)生不同的解釋和不同的執(zhí)行方式,通俗來講就是用一種類型的變量來引用不同的對象,從而調(diào)用不同的方法,產(chǎn)生不同的行為。多態(tài)是實現(xiàn)面向?qū)ο蟮能浖夹g(shù)中必不可少的一個內(nèi)容。
繼承和多態(tài)
讓我們以一只動物為例:狗是一種動物,它會跑;貓也是一種動物,它會走。如果我們想用一個方法來描述它們的運動行為,該怎么做呢?
我們可以先定義一個 Animal 類,里面包含一個 move() 方法,來描述它們共同的運動方式:
public class Animal { public void move() { System.out.println("動物正在移動"); } }
然后,我們可以在 Animal 的子類中,重寫 move() 方法,以實現(xiàn)不同的運動方式:
public class Dog extends Animal { public void move() { System.out.println("小狗在跑"); } } public class Cat extends Animal { public void move() { System.out.println("小貓在走"); } }
這里我們讓 Dog 類重寫了 move() 方法,實現(xiàn)了“跑”這種運動方式;而 Cat 類重寫了 move() 方法,實現(xiàn)了“走”這種運動方式。
最后,我們可以在主函數(shù)中,定義一個 Animal 類型的變量,并分別用 Dog 和 Cat 的實例來賦值,這樣我們就可以用相同的方法名 move() 來調(diào)用不同的實現(xiàn),即實現(xiàn)多態(tài)的效果:
public class Test { public static void main(String args[]) { Animal animal = new Animal(); Animal dog = new Dog(); Animal cat = new Cat(); animal.move(); // 輸出動物正在移動 dog.move(); // 輸出小狗在跑 cat.move(); // 輸出小貓在走 } }
在上述示例中,我們定義了 Animal 父類和 Dog、Cat 兩個子類。在主函數(shù)中,我們分別聲明了一個父類對象、一個 Dog 對象和一個 Cat 對象。當(dāng)我們調(diào)用它們的 move() 方法時,表示動物正在移動、小狗在跑和小貓在走,這就是多態(tài)的實現(xiàn)原理。
接口和多態(tài)
除了繼承,接口也可以幫助我們實現(xiàn)多態(tài)的功能。接口是指一組方法的集合,類可以實現(xiàn)這些方法并重寫它們。和繼承不同的是,一個類可以實現(xiàn)多個接口,從而實現(xiàn)多態(tài)的效果。
例如,我們可以定義一個接口 Run,其中包含一個 run() 方法,它表示一些可以奔跑的東西。然后我們可以在一個類中實現(xiàn)這個接口,并實現(xiàn)其中的方法,以表示具體的奔跑行為。最后,在代碼中,我們可以用接口類型來聲明一個變量,從而實現(xiàn)對多個實現(xiàn)類的引用。
下面是一個簡單的 Java 程序示例:
public interface Run { void run(); } public class Dog implements Run { public void run() { System.out.println("小狗在跑"); } } public class Cat implements Run { public void run() { System.out.println("小貓在走"); } } public class Test { public static void main(String[] args) { Run dog = new Dog(); Run cat = new Cat(); dog.run(); // 輸出小狗在跑 cat.run(); // 輸出小貓在走 } }
在上述示例中,我們定義了一個 Run 接口,它包含一個 run() 方法。然后我們可以在一個類中實現(xiàn)這個接口,并實現(xiàn)其中的方法,以表示具體的奔跑行為。最后,在主函數(shù)中,我們分別聲明了一個 Dog 類型、一個 Cat 類型的變量,并用它們的實例進行賦值和調(diào)用,從而實現(xiàn)多態(tài)的效果。
方法重載和多態(tài)
方法重載是指在同一個類或一個類的繼承結(jié)構(gòu)中,使用相同的方法名,但要求參數(shù)類型或個數(shù)不同,使得一個類擁有多個具有不同參數(shù)的方法,自動匹配到不同的方法實現(xiàn)。方法的重載可以讓我們更好地重用代碼和實現(xiàn)更加靈活的方法調(diào)用。
例如,我們可以重載一個 add() 方法,使得它既可以實現(xiàn)整數(shù)相加,又可以實現(xiàn)小數(shù)相加。在代碼中,我們可以用相同的方法名 add() 來調(diào)用這兩種不同的方法,最終調(diào)用的方法取決于實參類型。
下面是一個簡單的 Java 程序示例:
public class Calculation { public void add(int a, int b) { System.out.println("兩個整數(shù)相加的結(jié)果是:" + (a + b)); } public void add(double a, double b) { System.out.println("兩個小數(shù)相加的結(jié)果是:" + (a + b)); } } public class Test { public static void main(String args[]) { Calculation calculation = new Calculation(); calculation.add(10, 20); // 輸出兩個整數(shù)相加的結(jié)果是:30 calculation.add(1.2, 3.4); // 輸出兩個小數(shù)相加的結(jié)果是:4.6 } }
在上述示例中,我們定義了一個 Calculation 類,其中包含了兩個相同名稱、但參數(shù)類型不同的 add() 方法,一個是將兩個整數(shù)相加,另一個是將兩個小數(shù)相加。在主函數(shù)中,我們分別調(diào)用這兩個方法,并分別輸出它們的結(jié)果。這展示了編譯時多態(tài)的實現(xiàn)原理。
方法覆蓋和多態(tài)
方法覆蓋是指子類重寫了父類中的某個方法,并且子類中的方法和父類中的方法具有相同的方法名稱、返回類型和參數(shù)列表。當(dāng)我們使用父類類型來聲明一個變量,并將其賦值為子類的實例時,該變量將會調(diào)用子類中的方法,實現(xiàn)動態(tài)多態(tài)的效果。
例如,我們可以定義一個新的類 Panther,它繼承自 Animal 類,然后重寫了 move() 方法,以實現(xiàn)新的運動方式。最后,在主函數(shù)中,我們可以用 Animal 類型來聲明一個變量,并將其分別賦值為 Dog、Cat 和 Panther 的實例,用 move() 方法來調(diào)用它們的運動行為,實現(xiàn)動態(tài)多態(tài)的效果。
下面是一個簡單的 Java 程序示例:
public class Panther extends Animal { public void move() { System.out.println("黑豹在奔跑"); } } public class Test { public static void main(String[] args) { Animal animal1 = new Animal(); Animal animal2 = new Dog(); Animal animal3 = new Cat(); Animal animal4 = new Panther(); animal1.move(); // 輸出動物正在移動 animal2.move(); // 輸出小狗在跑 animal3.move(); // 輸出小貓在走 animal4.move(); // 輸出黑豹在奔跑 } }
在上述示例中,我們定義了一個 Panther 類,它繼承自 Animal 類,然后重寫了 move() 方法,以實現(xiàn)新的運動方式。在主函數(shù)中,我們分別聲明了一個父類對象、一個 Dog 對象、一個 Cat 對象和一個 Panther 對象,并用它們的實例進行賦值和調(diào)用,最終調(diào)用的方法取決于實際對象的類型,這就是運行時多態(tài)的實現(xiàn)原理。
多態(tài)原理分析
多態(tài)可以分為編譯時多態(tài)和運行時多態(tài)兩種。
運行時多態(tài)
運行時多態(tài)又稱動態(tài)多態(tài),是指在程序運行期間根據(jù)對象的類型來確定方法的調(diào)用。運行時多態(tài)是通過方法重寫和接口實現(xiàn)來實現(xiàn)的。
上述的動物類 Animal,它擁有一個 move() 方法來描述動物的運動行為,這個move() 具體調(diào)用哪個方法(Animal/Dog/Cat)在編譯期間是不知道的,它是在運行期間確定的,在運行期間給他傳入什么對象它就調(diào)用什么方法。
編譯時多態(tài)
編譯時多態(tài)又稱靜態(tài)多態(tài),是指在編譯期間就確定了方法的調(diào)用。編譯時多態(tài)是通過方法重載來實現(xiàn)的,即同一個類中有多個名稱、參數(shù)不同的方法,編譯器在調(diào)用這些方法時,會根據(jù)實參類型的不同來匹配相應(yīng)的方法。
通過JDBC理解動態(tài)
JDBC 是 Java 數(shù)據(jù)庫連接的標(biāo)準(zhǔn)接口,它允許 Java 應(yīng)用程序通過統(tǒng)一的接口訪問不同的數(shù)據(jù)庫。使用 JDBC 可以連接多種數(shù)據(jù)庫,如 MySQL、Oracle、SQL Server 等,這就要求 JDBC 具有語言無關(guān)性,可以在運行時動態(tài)確定將要連接的數(shù)據(jù)庫類型,這樣才能支持多種數(shù)據(jù)庫的連接。
JDBC 中用到的多態(tài)主要是運行時多態(tài)。JDBC 接口定義了一些通用的方法和接口,如 Connection、Statement、ResultSet 等,它們都是抽象類或接口。具體的數(shù)據(jù)庫驅(qū)動程序?qū)崿F(xiàn)了這些方法和接口,通過實現(xiàn)這些方法和接口,實現(xiàn)了連接到具體的數(shù)據(jù)庫。在連接數(shù)據(jù)庫時,我們通過 DriverManager 的 getConnection() 方法獲取 Connection 對象,此時是用的是 JDBC 接口,而不是具體的數(shù)據(jù)庫驅(qū)動連接,只有在使用 Connection 對象的時候才會動態(tài)判斷實際使用的數(shù)據(jù)庫類型。以下是一個簡單的 JDBC 連接 MySQL 數(shù)據(jù)庫的示例代碼:
String url = "jdbc:mysql://localhost:3306/test"; String username = "root"; String password = "123456"; Connection conn = DriverManager.getConnection(url, username, password);
在上述代碼中,我們只是通過 JDBC 接口連接到 MySQL 數(shù)據(jù)庫,并沒有使用具體的 MySQL 驅(qū)動程序。當(dāng)我們調(diào)用 conn.prepareStatement() 方法時,此時才根據(jù)具體的數(shù)據(jù)庫類型獲取到一個實現(xiàn)了 PreparedStatement 接口的對象,例如 MySQLPreparedStatement。這就是在運行時動態(tài)確定要使用的數(shù)據(jù)庫類型,實現(xiàn)了運行時多態(tài)的效果。
總之,JDBC 中充分利用了 Java 的多態(tài)特性,通過動態(tài)綁定技術(shù),實現(xiàn)了在不同數(shù)據(jù)庫之間切換時的語言無關(guān)性。JDBC 連接的抽象設(shè)計,可以讓我們編寫一次連接代碼,就可以連接多個數(shù)據(jù)庫,實現(xiàn)了代碼復(fù)用和可擴展性。
總結(jié)
多態(tài)是 Java 面向?qū)ο缶幊讨械闹匾拍睢K试S我們在編寫代碼時,只需要知道一個對象的類型,而無需知道它所具體屬于的子類類型。在 Java 中,多態(tài)的實現(xiàn)原理主要有兩種方式:運行時多態(tài)和編譯時多態(tài)。前者是通過方法的重寫實現(xiàn)的,后者則是通過方法的重載實現(xiàn)的。同時,多態(tài)也讓 Java 的代碼更加靈活、可擴展性更強。
以上就是深入淺出探究Java多態(tài)的實現(xiàn)和應(yīng)用的詳細內(nèi)容,更多關(guān)于Java多態(tài)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
java中int、double、char等變量的取值范圍詳析
這篇文章主要給大家介紹了關(guān)于java中int、double、char等變量取值范圍的相關(guān)資料,每個變量都給出了詳細的實例代碼,對大家學(xué)習(xí)或者使用java具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2021-10-10Spring?Boot?配置文件之類型、加載順序與最佳實踐記錄
Spring?Boot?的配置文件是靈活且強大的工具,通過合理的配置管理,可以讓應(yīng)用開發(fā)和部署更加高效,無論是簡單的屬性配置,還是復(fù)雜的多環(huán)境管理,Spring?Boot都提供了便捷的解決方案,本文介紹Spring?Boot?配置文件:類型、加載順序與最佳實踐,感興趣的朋友一起看看吧2025-04-04解析springboot集成AOP實現(xiàn)日志輸出的方法
如果這需要在每一個controller層去寫的話代碼過于重復(fù),于是就使用AOP定義切面 對其接口調(diào)用前后進行攔截日志輸出。接下來通過本文給大家介紹springboot集成AOP實現(xiàn)日志輸出,需要的朋友可以參考下2021-11-11SpringBoot實現(xiàn)輕量級動態(tài)定時任務(wù)管控及組件化的操作步驟
文章介紹了一種在SpringBoot中實現(xiàn)動態(tài)定時任務(wù)的解決方案,基于COLA架構(gòu)理論,封裝到了組件層,該組件支持類級別和方法級別的定時任務(wù)注冊,并提供了易用性和擴展性,組件使用Maven形式引入,并且可以通過YAML配置文件進行設(shè)置,感興趣的朋友一起看看吧2024-11-11JAVA?兩個類同時實現(xiàn)同一個接口的方法(三種方法)
在Java中,兩個類同時實現(xiàn)同一個接口是非常常見的,接口定義了一組方法,實現(xiàn)接口的類必須提供這些方法的具體實現(xiàn),以下將展示如何實現(xiàn)這一要求,并提供具體的代碼示例,需要的朋友可以參考下2024-08-08java實現(xiàn) 微博登錄、微信登錄、qq登錄實現(xiàn)代碼
這篇文章主要介紹了java實現(xiàn) 微博登錄、微信登錄、qq登錄實現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下2016-10-10