java多態的概念
1. 什麼叫做多態在java中
在JAVA中有兩種多態是指:運行時多態和編譯時多態。
關於類的多態性簡介如下:
多態(polymorphism)意為一個名字可具有多種語義.在程序設計語言中,多態性是指」一種定義,多種實現」.例如,運算符+有多種含義,究竟執行哪種運算取決於參加運算的操作數類型:
1+2 //加法運算符
「1」 + 「2」 //字元串連接運算,操作數是字元串
多態性是面向對象的核心特徵之一,類的多態性提供類中成員設計的靈活性和方法執行的多樣性.
1、類多態性表現
(1)方法重載
重載表現為同一個類中方法的多態性.一個類生命多個重載方法就是為一種功能提供多種實現.編譯時,根據方法實際參數的數據類型\個數和次序,決定究竟應該執行重載方法中的哪一個.
(2)子類重定義從父類繼承來的成員
當子類從父類繼承來的成員不適合子類時,子類不能刪除它們,但可以重定義它們,使弗雷成員適應子類的新需求.子類重定義父類成員,同名成員在父類與子類之間表現出多態性,父類對象引用父類成員,子類對象引用子類成員,不會產生沖突和混亂.
子類可重定義父類的同名成員變數,稱子類隱藏父類成員變數.子類也可以重定義父類的同名成員方法,當子類方法的參數列表與父類方法參數列表完全相同時,稱為子類方法覆蓋(override)父類方法。覆蓋父類方法時,子類方法的訪問許可權不能小於父類方法的許可權。
由於Object類的equals()方法比較兩個對象的引用是否相等而不是值是否相等,因此一個類要覆蓋Object類的equals()方法,提供本類兩個對象比較相等方法.
覆蓋表現為父類與子類之間方法的多態性.java 尋找執行方法的原則是:從對象所屬的類開始,尋找匹配的方法執行,如果當前類中沒有匹配的方法,則逐層向上依次在父類或祖先類中尋找匹配方法,直到Object類.
2、super 引用
在子類的成員方法中,可以使用代詞super引用父類成員.super引用的語法如下:
super([參數列表]) //在子類的構造方法體中,調用父類的構造方法
super.成員變數 //當子類隱藏父類成員變數時,引用父類同名成員變數
super.成員方法([參數列表]) //當子類覆蓋父類成員方法時,調用父類同名成員方法
*注意:super引用沒有單獨使用的語法
3、多態性有兩種:
1)編譯時多態性
對於多個同名方法,如果在編譯時能夠確定執行同名方法中的哪一個,則稱為編譯時多態性.
2)運行時多態性
如果在編譯時不能確定,只能在運行時才能確定執行多個同名方法中的哪一個,則稱為運行時多態性.
方法覆蓋表現出兩種多態性,當對象獲得本類實例時,為編譯時多態性,否則為運行時多態性,例如:
XXXX x1 = new XXXX(參數列表); //對象獲得本類實例,對象與其引用的實例類型一致
XXX xx1 = new XXX(參數列表);
x1.toString(); //編譯時多態性,執行XXX類的方法.
xx1.toString(); //編譯時多態性,執行XXXX類覆蓋的方法.
XXXX為XXX的父類.
由於子類對象既是父類對象,父類對象與子類對象之間具有賦值相容性,父類對象能夠被賦值為子類對象.例如,
XXXX x2 = new XXX(參數列表); //父類對象獲得子類實例,子類對象即是父類對象
x2.toString(); //運行時多態
x2聲明為父類對象卻獲得子類XXX的實例,那麼x2.toString()究竟執行父類方法還是執行子類覆蓋的方法呢?
這分為兩種情況:
取決於子類是否覆蓋父類方法.如果子類覆蓋父類方法,則執行子類方法;
如果沒有覆蓋,則執行父類方法.
在編譯時,僅僅依據對象所屬的類,系統無法確定到底應該執行那個類的方法,只有運行時才能確定,因此這是運行時多態.
父類對象並不能執行所有的子類方法,只能執行那些父類中聲明\子類覆蓋的子類方法.
2. java中多態性什麼意思
多態性:顧名思義就是擁有「多種形態」的含義,是指屬性或方法在子類中表現為多種形態。
在JAVA中有兩種多態是指:運行時多態和編譯時多態。多態性是面向對象的核心特徵之一,類的多態性提供類中成員設計的靈活性和方法執行的多樣性。
多態指允許不同類的對象對同一消息做出響應。即同一消息可以根據發送對象的不同而採用多種不同的行為方式。(發送消息就是函數調用)
實現多態的技術稱為:動態綁定(dynamic binding),是指在執行期間判斷所引用對象的實際類型,根據其實際的類型調用其相應的方法。
擴展資料:
多態的好處:
1、可替換性(substitutability)多態對已存在代碼具有可替換性。例如,多態對圓Circle類工作,對其他任何圓形幾何體,如圓環,也同樣工作。
2、可擴充性(extensibility)多態對代碼具有可擴充性。增加新的子類不影響已存在類的多態性、繼承性,以及其他特性的運行和操作。實際上新加子類更容易獲得多態功能。
3、介面性(interface-ability)多態是超類通過方法簽名,向子類提供了一個共同介面,由子類來完善或者覆蓋它而實現的。
4、靈活性(flexibility)它在應用中體現了靈活多樣的操作,提高了使用效率。
5、簡化性(simplicity)多態簡化對應用軟體的代碼編寫和修改過程,尤其在處理大量對象的運算和操作時,這個特點尤為突出和重要。
3. java中多態的定義是什麼
多態性是指允許不同類的對象對同一消息作出響應,多態性包括參數化多態性和包含多態性,多態性語言具有靈活、抽象、行為共享、代碼共享的優勢,很好的解決了應用程序函數同名問題。
多態有兩種表現形式:重載和覆蓋
1、首先說重載(overload),是發生在同一類中,與什麼父類子類、繼承毫無關系。
標識一個函數除了函數名外,還有函數的參數(個數和類型),也就是說,一個類中可以有兩個或更多的函數,叫同一個名字而他們的參數不同。
他們之間毫無關系,是不同的函數,只是可能他們的功能類似,所以才命名一樣,增加可讀性,僅此而已!
2、再說覆蓋(override),是發生在子類中,也就是說必須有繼承的情況下才有覆蓋發生。
繼承一個類,也就有了父類了全部方法,如果你感到哪個方法不爽,功能要變,那就把那個函數在子類中重新實現一遍。
這樣再調用這個方法的時候,就是執行子類中的過程了,父類中的函數就被覆蓋了。
4. java 多態怎麼回事,如何實現
出自:http://..com/question/42014727.html
一、基本概念
多態性:發送消息給某個對象,讓該對象自行決定響應何種行為。
通過將子類對象引用賦值給超類對象引用變數來實現動態方法調用。
java 的這種機制遵循一個原則:當超類對象引用變數引用子類對象時,被引用對象的類型而不是引用變數的類型決定了調用誰的成員方法,但是這個被調用的方法必須是在超類中定義過的,也就是說被子類覆蓋的方法。
1. 如果a是類A的一個引用,那麼,a可以指向類A的一個實例,或者說指向類A的一個子類。
2. 如果a是介面A的一個引用,那麼,a必須指向實現了介面A的一個類的實例。
二、Java多態性實現機制
SUN目前的JVM實現機制,類實例的引用就是指向一個句柄(handle)的指針,這個句柄是一對指針:
一個指針指向一張表格,實際上這個表格也有兩個指針(一個指針指向一個包含了對象的方法表,另外一個指向類對象,表明該對象所屬的類型);
另一個指針指向一塊從java堆中為分配出來內存空間。
The Java Virtual Machine does not require any particular internal structure for objects. In Sun 's current implementation of the Java Virtual Machine, a reference to a class instance is a pointer to a handle that is itself a pair of pointers: one to a table containing the methods of the object and a pointer to the Class object that represents the type of the object, and the other to the memory allocated from the Java heap for the object data. (jvm規范中關於對象內存布局的說明)
三、總結
1、通過將子類對象引用賦值給超類對象引用變數來實現動態方法調用。
DerivedC c2=new DerivedC();
BaseClass a1= c2; //BaseClass 基類,DerivedC是繼承自BaseClass的子類
a1.play(); //play()在BaseClass,DerivedC中均有定義,即子類覆寫了該方法
分析:
* 為什麼子類的類型的對象實例可以覆給超類引用?
自動實現向上轉型。通過該語句,編譯器自動將子類實例向上移動,成為通用類型BaseClass;
* a.play()將執行子類還是父類定義的方法?
子類的。在運行時期,將根據a這個對象引用實際的類型來獲取對應的方法。所以才有多態性。一個基類的對象引用,被賦予不同的子類對象引用,執行該方法時,將表現出不同的行為。
在a1=c2的時候,仍然是存在兩個句柄,a1和c2,但是a1和c2擁有同一塊數據內存塊和不同的函數表。
2、不能把父類對象引用賦給子類對象引用變數
BaseClass a2=new BaseClass();
DerivedC c1=a2;//出錯
在java裡面,向上轉型是自動進行的,但是向下轉型卻不是,需要我們自己定義強制進行。
c1=(DerivedC)a2; 進行強制轉化,也就是向下轉型.
3、記住一個很簡單又很復雜的規則,一個類型引用只能引用引用類型自身含有的方法和變數。
你可能說這個規則不對的,因為父類引用指向子類對象的時候,最後執行的是子類的方法的。
其實這並不矛盾,那是因為採用了後期綁定,動態運行的時候又根據型別去調用了子類的方法。而假若子類的這個方法在父類中並沒有定義,則會出錯。
例如,DerivedC類在繼承BaseClass中定義的函數外,還增加了幾個函數(例如 myFun())
分析:
當你使用父類引用指向子類的時候,其實jvm已經使用了編譯器產生的類型信息調整轉換了。
這里你可以這樣理解,相當於把不是父類中含有的函數從虛擬函數表中設置為不可見的。注意有可能虛擬函數表中有些函數地址由於在子類中已經被改寫了,所以對象虛擬函數表中虛擬函數項目地址已經被設置為子類中完成的方法體的地址了。
配合這到體有助理解:http://..com/question/123628003.html
5. JAVA中的多態
Java中的多態主要指兩方面:
1.方法的重載:根據相同的方法名和不同的參數形式,可以調用功能不同的方法。
2.方法的重寫:子類中方法名和參數形式、返回值類型與父類一致,可以實現方法功能的重寫。
子類重寫的方法同名覆蓋了父類中原來的方法,子類對象或上轉型對象調用該方法時,調用的是子類中重寫的方法。不同的子類中可以分別重寫功能不同的方法。
用上轉型對象調用該方法時,根據當時所控制的對象類型不同(為上轉型對象賦值不同),可以實現不同的方法功能。