您好,登錄后才能下訂單哦!
這篇文章主要介紹了JAVA中動態性實例分析的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇JAVA中動態性實例分析文章都會有所收獲,下面我們一起來看看吧。
//下面我結合實例解釋一下Java中動態性實現問題
class base
{
public int ageOfBase=10;
public void display()
{
System.out.println("display() in base!");
}
public void display1()
{
System.out.println("display1() in base!");
}
private void show()
{
System.out.println("show() in base!");
}
}
class test extends base
{
public int ageOfTest=10;
/*這個函數改寫父類方法
但是他并不是簡單完成自己的功能;
在實現自己的應該實現的功能同時他還保留了父類的功能
*************************************
重要的是如果你沒有改寫這個父類方法的話,
子類test還是存在這樣的方法的,只是存在的方法
實際上是從父類繼承來的,只是簡單的實現父類
實現的功能。
*/
public void display()
{
System.out.println("display() in test!");
super.display();
}
//注意我并沒有改寫方法display1(),但是這個方法由于繼承的原因
//子類test中還是存在的
//我寫一個新的方法為子類
public void display2()
{
//這里引用父類的私有方法
//這個方法在子類中并不存在的
//但是一定要記住:
//訪問父類的私有成員是不允許的
//super.show();
//這里引用父類的共有方法
//實際上這里引用是子類中的方法
//因為這個方法已經從父類繼承了
display1();
//下面這樣引用也可以的
//這里是真正引用父類的方法的
// super.display1();
//上面這一點可能講的不是很清楚的
//下面我換一種例子
//這個是子類的
display();
//這個是父類的方法
super.display();
System.out.println("display2()in test!");
}
public static void main(String args[])
{
test t=new test();
base b=new base();
//下面這一句是多態性的根本
//一個父類的引用指向子類
b=t;
//這樣通過父類的引用調用方法的話
//實際上是執行子類中實現的方法
/*
下面我結合我對面向對象編程的掌握和研究情況談一下我的經驗和看法
其間我不能保證我說的每一點都正確,只是給你參考
對于多態性這個面向對象編程領域很重要的概念。我結合c++以及針對java中
的實際情況做幾點說明。
(1)最好對于虛擬指針以及虛擬指針表格有一定了解。
不了解的話,你只能是記住我說的,但是不一定能理解很好。
(2)父類引用指向子類。方法調用的時候執行的是子類的方法。
這個說法是有很多前提和意外的。
下面我舉一個例子
*/
b.display();
//****************原來文章表述有錯誤開始***********************
// 下面調用會出錯的()
//t.display2();
//********************原文表述錯誤結束*******************
//現在應該改成下面的描述
//下面這行應該改為b.display()
//這樣才能結合本文舉的例子。同時下面一行是可以運行的。
//對于這樣的寫作失誤,作者表示鄭重道歉
//************************************************************
//應該象下面那樣
((test)b).display2();
int temp1=b.ageOfBase;
// 下面調用會出錯
//int temp2=t.ageOfTest;
//應該向下面那樣
int temp2=((test)b).ageOfTest;
/*
現在解釋上面兩個會出錯的原因,這個原因是動態性的根本所在。
我盡力能解釋清楚一點。
**************關鍵一********************
因為父類和子類的對象在內存中的大小是不一樣的,當然了
不同的對象本身就不可能是同一塊內存地址的。
這個應該沒有問題的吧,當然了要是子類中只是簡單的
繼承而沒有都沒有做的話,可能是一樣的,但是在c++中
各家編譯器還有會有一點差異的,可能也會不一樣的。
***************關鍵二************************
引用本質上是通過指針來實現的,更深入一點是引用是指向指針的指針,
而不同類型的指針所管理的內存空間大小是不一樣的,這一點跟上面
聯系很緊的。注意這里是說指針管理的內存而不是指針,我想大家都
知道指針只有4個字節長度的。這里我們可以簡單的說是變量的可見性
問題,因為變量雖然存在但是并不一定是可見的。
***************關鍵三************************
多態性的關鍵是動態綁定,說白了就是虛擬函數虛擬指針虛擬指針表
等幾個重要的概念。簡單講一下,這里很復雜的,但是每一個真正的
面向對象編程人員必須花時間很好的理解這一點。java 中只有靜態函數
和虛擬函數兩種,c++中還有一種 非靜態非虛擬函數。所以java的動態
綁定要容易一點的。 你可以不精確的這樣理解(因為解釋精確我也很懶,
可以寫很長的文章了),每次類編譯的時候都會生成一個虛擬函數表,
表里面保存自己類中所有的虛擬函數地址,同時要是這個類存在父類
(不管是extends class 還是implements interface)的話,同時他會把
從父類繼承來的虛擬函數表也繼承過來(這里我只是大概解釋,不是很準確)。
這個地方請注意:
************************************************
要是子類沒有改寫父類繼承的方法,父類虛擬函數中對應虛擬函數地址
被變成子類自己的虛擬函數地址;如果沒有改變則不需要改變繼承來的
虛擬函數表對應函數的地址。
*************************************************
***************開始解釋************************
當父類引用指向子類對象的時候,父類引用管理的內存空間,
是要比子類真實的內存空間小的。所以子類中比父類中多的
東西對于這個父類引用來說是不可見的。所以也就沒有辦法引用。
上面的那個變量引用和函數引用就是這樣的,因為父類中沒有
變量ageOfTest和函數display2()的。但是我們可以知道父類指針
實際上是指向子類的,所以我們解決這個問題的方法就是:
強制轉換類型(java中叫造型)。
同時可能有人要問,子類中那個函數地址不是也在虛擬函數表中嗎?
很高興你問這樣的問題,但是父類引用看到的虛擬函數表是沒有
那個函數項目的,因為他對于父類引用絕對是不可見。
對于另外一個虛擬函數調用,如果你看了說明很仔細的話,你現在一定
知道雖然是父類引用管理內存范圍小,但是那個虛擬函數表,父類中有的,
但是由于函數被子類中改寫了,所以那個表中函數地址編程子類的拉,
當然就是引用子類的方法了。
/****************重要補充************************
java中靜態函數是沒有動態性,因為靜態函數不能被繼承,也不能被
改寫為非靜態方法。因為靜態就意味著類的所有實例共享一個實體。
**************************************************
*/
}
}
關于“JAVA中動態性實例分析”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“JAVA中動態性實例分析”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。