Java多態(tài)和實(shí)現(xiàn)接口的類的對(duì)象賦值給接口引用的方法(推薦)
接口的靈活性就在于“規(guī)定一個(gè)類必須做什么,而不管你如何做”。
我們可以定義一個(gè)接口類型的引用變量來引用實(shí)現(xiàn)接口的類的實(shí)例,當(dāng)這個(gè)引用調(diào)用方法時(shí),它會(huì)根據(jù)實(shí)際引用的類的實(shí)例來判斷具體調(diào)用哪個(gè)方法,這和上述的超類對(duì)象引用訪問子類對(duì)象的機(jī)制相似。
//定義接口InterA interface InterA { void fun(); } //實(shí)現(xiàn)接口InterA的類B class B implements InterA { public void fun() { System.out.println(“This is B”); } } //實(shí)現(xiàn)接口InterA的類C class C implements InterA { public void fun() { System.out.println(“This is C”); } } class Test { public static void main(String[] args) { InterA a; a= new B(); a.fun(); a = new C(); a.fun(); } }
輸出結(jié)果為:
This is B This is C
上例中類B和類C是實(shí)現(xiàn)接口InterA的兩個(gè)類,分別實(shí)現(xiàn)了接口的方法fun(),通過將類B和類C的實(shí)例賦給接口引用a,實(shí)現(xiàn)了方法在運(yùn)行時(shí)的動(dòng)態(tài)綁定,充分利用了“一個(gè)接口,多個(gè)方法”,展示了Java的動(dòng)態(tài)多態(tài)性。
需要注意的一點(diǎn)是:Java在利用接口變量調(diào)用其實(shí)現(xiàn)類的對(duì)象的方法時(shí),該方法必須已經(jīng)在接口中被聲明,而且在接口的實(shí)現(xiàn)類中該實(shí)現(xiàn)方法的類型和參數(shù)必須與接口中所定義的精確匹配。
--------------------------------------------------------------------------------
擴(kuò)展
Java運(yùn)行時(shí)多態(tài)性:繼承和接口的實(shí)現(xiàn)
Java是面向?qū)ο蟮恼Z言,而運(yùn)行時(shí)多態(tài)性是面向?qū)ο蟪绦蛟O(shè)計(jì)代碼重用的一個(gè)最強(qiáng)大機(jī)制,動(dòng)態(tài)性的概念也可以被說成“一個(gè)接口,多個(gè)方法”。Java實(shí)現(xiàn)運(yùn)行時(shí)多態(tài)性的基礎(chǔ)是動(dòng)態(tài)方法調(diào)度,它是一種在運(yùn)行時(shí)而不是在編譯期調(diào)用重載方法的機(jī)制,下面就繼承和接口實(shí)現(xiàn)兩方面談?wù)刯ava運(yùn)行時(shí)多態(tài)性的實(shí)現(xiàn)。
一、通過繼承中超類對(duì)象引用變量引用子類對(duì)象來實(shí)現(xiàn)
舉例說明:
//定義超類superA class superA { int i = 100; void fun() { System.out.println(“This is superA”); } } //定義superA的子類subB class subB extends superA { int m = 1; void fun() { System.out.println(“This is subB”); } } //定義superA的子類subC class subC extends superA { int n = 1; void fun() { System.out.println(“This is subC”); } } class Test { public static void main(String[] args) { superA a; subB b = new subB(); subC c = new subC(); a = b; a.fun(); (1) a = c; a.fun(); (2) } }
運(yùn)行結(jié)果為:
This is subB This is subC
上述代碼中subB和subC是超類superA的子類,我們?cè)陬怲est中聲明了3個(gè)引用變量a, b, c,通過將子類對(duì)象引用賦值給超類對(duì)象引用變量來實(shí)現(xiàn)動(dòng)態(tài)方法調(diào)用。也許有人會(huì)問:“為什么(1)和(2)不輸出:This is superA”。java 的這種機(jī)制遵循一個(gè)原則:當(dāng)超類對(duì)象引用變量引用子類對(duì)象時(shí),被引用對(duì)象的類型而不是引用變量的類型決定了調(diào)用誰的成員方法,但是這個(gè)被調(diào)用的方法必須是在超類中定義過的,也就是說被子類覆蓋的方法。
所以,不要被上例中(1)和(2)所迷惑,雖然寫成a.fun(),但是由于(1)中的a被b賦值,指向了子類subB的一個(gè)實(shí)例,因而(1)所調(diào)用的fun()實(shí)際上是子類subB的成員方法fun(),它覆蓋了超類superA的成員方法fun();同樣(2)調(diào)用的是子類subC的成員方法fun()。
另外,如果子類繼承的超類是一個(gè)抽象類,雖然抽象類不能通過new操作符實(shí)例化,但是可以創(chuàng)建抽象類的對(duì)象引用指向子類對(duì)象,以實(shí)現(xiàn)運(yùn)行時(shí)多態(tài)性。具體的實(shí)現(xiàn)方法同上例。
不過,抽象類的子類必須覆蓋實(shí)現(xiàn)超類中的所有的抽象方法,否則子類必須被abstract修飾符修飾,當(dāng)然也就不能被實(shí)例化了。
二、通過接口類型變量引用實(shí)現(xiàn)接口的類的對(duì)象來實(shí)現(xiàn)
接口的靈活性就在于“規(guī)定一個(gè)類必須做什么,而不管你如何做”。我們可以定義一個(gè)接口類型的引用變量來引用實(shí)現(xiàn)接口的類的實(shí)例,當(dāng)這個(gè)引用調(diào)用方法時(shí),它會(huì)根據(jù)實(shí)際引用的類的實(shí)例來判斷具體調(diào)用哪個(gè)方法,這和上述的超類對(duì)象引用訪問子類對(duì)象的機(jī)制相似。
舉例說明:
//定義接口InterA interface InterA { void fun(); } //實(shí)現(xiàn)接口InterA的類B class B implements InterA { public void fun() { System.out.println(“This is B”); } } //實(shí)現(xiàn)接口InterA的類C class C implements InterA { public void fun() { System.out.println(“This is C”); } } class Test { public static void main(String[] args) { InterA a; a= new B(); a.fun(); a = new C(); a.fun(); } }
輸出結(jié)果為:
This is B This is C
上例中類B和類C是實(shí)現(xiàn)接口InterA的兩個(gè)類,分別實(shí)現(xiàn)了接口的方法fun(),通過將類B和類C的實(shí)例賦給接口引用a而實(shí)現(xiàn)了方法在運(yùn)行時(shí)的動(dòng)態(tài)綁定,充分利用了“一個(gè)接口,多個(gè)方法”展示了Java的動(dòng)態(tài)多態(tài)性。
需要注意的一點(diǎn)是:Java在利用接口變量調(diào)用其實(shí)現(xiàn)類的對(duì)象的方法時(shí),該方法必須已經(jīng)在接口中被聲明,而且在接口的實(shí)現(xiàn)類中該實(shí)現(xiàn)方法的類型和參數(shù)必須與接口中所定義的精確匹配。
結(jié)束語:以上就是java運(yùn)行時(shí)多態(tài)性的實(shí)現(xiàn)方法,大家在編程過程中可以靈活運(yùn)用,但是在性能要求較高的代碼中不提倡運(yùn)用運(yùn)行時(shí)多態(tài),畢竟Java的運(yùn)行時(shí)動(dòng)態(tài)方法調(diào)用較之普通的方法調(diào)用的系統(tǒng)開銷是比較大的。
--------------------------------------------------
Java靜態(tài)方法不具有多態(tài)性詳解
動(dòng)態(tài)綁定機(jī)制使得基類的引用能夠指向正確的子類對(duì)象,從而使得面向基類編程成為可能。
然而動(dòng)態(tài)綁定在以下兩種情況會(huì)失效。
1、基類方法是private或final修飾的
這個(gè)很好理解,因?yàn)閜rivate說明該方法對(duì)子類是不可見的,子類再寫一個(gè)同名的方法并不是對(duì)父類方法進(jìn)行復(fù)寫(Override),而是重新生成一個(gè)新的方法,也就不存在多態(tài)的問題了。同理也可以解釋final,因?yàn)榉椒ㄍ瑯邮遣豢筛采w的。
2、方法是static修飾的
代碼如下所示.
class Base { public static void staticMethod() { System.out.println("Base staticMehtod"); } public void dynamicMehtod() { System.out.println("Base dynamicMehtod"); } } class Sub extends Base { public static void staticMethod() { System.out.println("Sub staticMehtod"); } public void dynamicMehtod() { System.out.println("Sub dynamicMehtod"); } } public class TJ4 { public static void main(String args[]) { Base c = new Sub(); c.staticMethod(); c.dynamicMehtod(); } }
輸出結(jié)果如下:
Base staticMehtod Sub dynamicMehtod
輸出結(jié)果并不像設(shè)想的那樣,輸出 “Sub staticMehtod”。因?yàn)殪o態(tài)方法是與類而不是與某個(gè)對(duì)象相關(guān)聯(lián),c.staticMethod();等同于Car.staticMethod(); 所以盡量不要使用實(shí)例變量去調(diào)用靜態(tài)方法,避免混淆。
以上這篇Java多態(tài)和實(shí)現(xiàn)接口的類的對(duì)象賦值給接口引用的方法(推薦)就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
java實(shí)現(xiàn)MapReduce對(duì)文件進(jìn)行切分的示例代碼
本文主要介紹了java實(shí)現(xiàn)MapReduce對(duì)文件進(jìn)行切分的示例代碼,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01使用springBoot項(xiàng)目配置文件位置調(diào)整到打包外
這篇文章主要介紹了使用springBoot項(xiàng)目配置文件位置調(diào)整到打包外,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-08-08SpringBoot項(xiàng)目中Controller接收兩個(gè)實(shí)體的實(shí)現(xiàn)方法
本文主要介紹了SpringBoot項(xiàng)目中Controller接收兩個(gè)實(shí)體的實(shí)現(xiàn)方法,主要介紹了兩種方法,具有一定的參考價(jià)值,感興趣的可以了解一下2023-08-08SpringBoot validator參數(shù)驗(yàn)證restful自定義錯(cuò)誤碼響應(yīng)方式
這篇文章主要介紹了SpringBoot validator參數(shù)驗(yàn)證restful自定義錯(cuò)誤碼響應(yīng)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10詳解Springboot如何通過注解實(shí)現(xiàn)接口防刷
本文主要為大家介紹一種極簡(jiǎn)潔、靈活通用接口防刷實(shí)現(xiàn)方式、通過在需要防刷的方法加上@Prevent?注解即可實(shí)現(xiàn)短信防刷,感興趣的可以了解一下2022-09-09Java Swing組件編程之JTable表格用法實(shí)例詳解
這篇文章主要介紹了Java Swing組件編程之JTable表格用法,結(jié)合實(shí)例形式詳細(xì)分析了Swing組件中JTable表格的常見定義與使用方法,需要的朋友可以參考下2017-11-11