java 對象實例化過程中的多態特性解析
java 對象實例化過程中的多態特性
執行對象實例化過程中遵循多態特性 ==> 調用的方法都是實例化的子類中的重寫方法,隻有明確調用瞭super.xxx關鍵詞或者是子類中沒有該方法時,才會去調用父類相同的同名方法。
通過案例說明
package com.njau.test1; class Test { public static void main(String[] args) { System.out.println(new B().getValue()); } static class A { protected int value; public A (int v) { setValue(v); } public void setValue(int value) { this.value= value; } public int getValue() { try { value ++; return value; } finally { this.setValue(value); System.out.println(value); } } } static class B extends A { public B () { super(5); setValue(getValue()- 3); } public void setValue(int value) { super.setValue(2 * value); } } }
通過上述代碼
始終明確調用的方法必須是實例化子類中重寫的方法。
首先,在main函數中,【new B()】new瞭一個B類的實例化對象,在實例化對象時,調用瞭B類中的構造函數,執行【super(5)】,也就是public A(int v)——>setValue(v),由於調用的方法必須是實例化子類中重寫的方法的原則。因此,這裡調用的是B類中的setValue(v)方法,此時B實例的value值設置為2 x 5 = 10,後執行super.setValue(10),將value=10的值存儲起來。
執行完super(5)後,執行構造函數中的【setValue(getValue()- 3)】中【getValue()】,由於B類中沒有getValue()方法,則調用父類(A類)中的getValue()方法,value++所得到的值為11,並存儲在value中(先執行finally中的部分,後執行try中的return),在finally中,調用瞭【this.setValue(value)】,由於調用的方法必須是實例化子類中重寫的方法的原則,調用的是B類中的setValue(v)方法,此時B實例的value值設置為2 x 11= 22,之後執行System.out.println(value)
即在控制臺上打印22
執行完finally中的部分,後執行try中的return,將value++執行後,存儲在value中的11,return回去;執行【setValue(getValue()- 3)】,即:setValue(8)
執行setValue(8)時,由於調用的方法必須是實例化子類中重寫的方法的原則,則調用B類中的setValue(v)方法,此時B實例的value值設置為2 x 8= 16;此時B類中的構造函數執行結束。
在實例化對象以後,執行【new B().getValue()】,由於B類中沒有getValue()方法,則調用父類(A類)中的getValue()方法,value++所得到的值為17,並存儲在value中,在finally中,調用瞭【this.setValue(value)】,由於調用的方法必須是實例化子類中重寫的方法的原則,調用的是B類中的setValue(v)方法,此時B實例的value值設置為2 x 17= 34,之後執行System.out.println(value)
即在控制臺上打印34
執行完finally中的部分,後執行try中的return,將value++執行後,存儲在value中的17,return回去;執行【System.out.println(new B().getValue())】
即在控制臺上打印17
value值的變化過程,僅解釋實例化對象時,構造函數中:super(5)與setValue(getValue()+3)兩部分。圖中兩條線,起點分別為【new B()】與【setValue(getValue()+3)】:
執行結果為:
java對象的三個特性(封裝、繼承、多態)
類(類型)和對象:對象是獨一無二的。對象有其所屬之類型。對象是類型的一個具體的實例。
創建編寫一個 class :定義一個類型。類型是編寫出來的,即使程序不運行,類型已然存在。
對象:對象是new出來的,在程序運行期間new出來的,存在於內存中(堆中 )。如果程序未運行,則對象不存在。
對象的三大特性:
1.封裝
1.1 把本屬於某個類型的成員屬性(靜態特性)和職責(動態特性)定義到一個類中。
1.2 訪問權限控制:使用權限訪問修飾符控制成員(屬性和方法)的訪問(可見性)。
private
:最小訪問權限,僅限類的內部可以訪問。<無修飾符>
:包修飾符,友好訪問修飾符,類內,包內可以訪問。protected
:類內,包內,子類可以訪問。public
:類內,包內,子類,包外都可以訪問。
類的兩大成員:
1.屬性:有默認值,0 0.0 false ‘\0’ null。引用類型的默認值是null值。
2.方法:方法中,可以訪問成員屬性。
構造方法:
用於構造對象(對對象進行成員屬性初始化),構造對象的過程可能簡單,也可能復雜。
- 和類同名。語法:new 構造方法(參數列表)
- 無返回值。其作用僅為構造對象。
- 構造方法可以重載。
this關鍵字:
- 訪問當前對象的屬性和方法。
- this(參數列表),隻能放在構造方法的第一行,並且隻能單獨使用。
- 當方法的參數和成員屬性名稱沖突的時候,可以使用this進行區分。
2.繼承
2.1 為什麼要繼承:消除重復。子類可以繼承父類的某些成員。
2.2 extends 關鍵字:擴展。一個類隻能繼承一個父類。如果沒有指定父類的話,則默認繼承自Object類。Object類是根類型,終級類,沒有父類。其它一切引用類型都是直接或間接繼承自Object類型。
2.3 什麼成員可以被繼承?1. 私有成員不能被繼承。2. 構造方法不能被繼承。
2.4 子類對象構造的過程:按照繼承的順序,遞歸創建各類型的狀態值。
3.多態
同一個類型所展現出的行為或屬性的多種形態。
使用父類(祖先類、接口)的引用指向子類(派生類,實現類)的對象。
多態的使用場景:某些場景,隻希望關註某些(不同的具體類型)類型的共性(祖先類,接口),而忽略其它獨特的特性。
final:
- 修飾類,表示類不可被繼承。
- 修飾方法,表示方法不能被重寫。
- 修飾成員屬性,或者普通變量,表示值不可修改。
static:靜態的
- 一旦屬性和方法,添加瞭static關鍵字,表示屬性和方法是屬於類的,而不是屬於某一個具體的對象的。
- 通過“類名.靜態成員”來訪問,而無須先創建對象。
抽象類:
- 當定義一個類時,如果某個方法暫時不便實現,或者無法實現,或者不適合實現,或者希望具體的子類來提供實現,可以使用abstract關鍵字來修飾此方法,表示抽象方法,抽象方法無需提供實現。
- 當一個類中存在抽象方法時,類必須定義成抽象類。但是,一個抽象類中可以沒有抽象方法。
- 抽象類不能實例化,但可以定義構造方法。
- 抽象類是類,擁有一切類的特性,除瞭不能實例化。
接口:
- 接口不是類。但是接口和抽象類類似。
- 接口中的方法全都是公有的抽象方法。jdk8之前。
- 接口中的屬性,都是公有的靜態的最終的。
- 接口需要類來提供實現。implements關鍵字。一個類可以實現多個接口,相當於將所有這些接口的方法提供實現。
- 接口可以繼承接口,使用 extends 關鍵字。
- 接口也可以使用多態特性,使用接口的引用指向實現類的實例。
- 接口的主要目的(作用)就是多態。
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。