您好,登錄后才能下訂單哦!
這篇文章主要介紹了JAVA中動(dòng)態(tài)性實(shí)例分析的相關(guān)知識(shí),內(nèi)容詳細(xì)易懂,操作簡單快捷,具有一定借鑒價(jià)值,相信大家閱讀完這篇JAVA中動(dòng)態(tài)性實(shí)例分析文章都會(huì)有所收獲,下面我們一起來看看吧。
//下面我結(jié)合實(shí)例解釋一下Java中動(dòng)態(tài)性實(shí)現(xiàn)問題
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;
/*這個(gè)函數(shù)改寫父類方法
但是他并不是簡單完成自己的功能;
在實(shí)現(xiàn)自己的應(yīng)該實(shí)現(xiàn)的功能同時(shí)他還保留了父類的功能
*************************************
重要的是如果你沒有改寫這個(gè)父類方法的話,
子類test還是存在這樣的方法的,只是存在的方法
實(shí)際上是從父類繼承來的,只是簡單的實(shí)現(xiàn)父類
實(shí)現(xiàn)的功能。
*/
public void display()
{
System.out.println("display() in test!");
super.display();
}
//注意我并沒有改寫方法display1(),但是這個(gè)方法由于繼承的原因
//子類test中還是存在的
//我寫一個(gè)新的方法為子類
public void display2()
{
//這里引用父類的私有方法
//這個(gè)方法在子類中并不存在的
//但是一定要記住:
//訪問父類的私有成員是不允許的
//super.show();
//這里引用父類的共有方法
//實(shí)際上這里引用是子類中的方法
//因?yàn)檫@個(gè)方法已經(jīng)從父類繼承了
display1();
//下面這樣引用也可以的
//這里是真正引用父類的方法的
// super.display1();
//上面這一點(diǎn)可能講的不是很清楚的
//下面我換一種例子
//這個(gè)是子類的
display();
//這個(gè)是父類的方法
super.display();
System.out.println("display2()in test!");
}
public static void main(String args[])
{
test t=new test();
base b=new base();
//下面這一句是多態(tài)性的根本
//一個(gè)父類的引用指向子類
b=t;
//這樣通過父類的引用調(diào)用方法的話
//實(shí)際上是執(zhí)行子類中實(shí)現(xiàn)的方法
/*
下面我結(jié)合我對面向?qū)ο缶幊痰恼莆蘸脱芯壳闆r談一下我的經(jīng)驗(yàn)和看法
其間我不能保證我說的每一點(diǎn)都正確,只是給你參考
對于多態(tài)性這個(gè)面向?qū)ο缶幊填I(lǐng)域很重要的概念。我結(jié)合c++以及針對java中
的實(shí)際情況做幾點(diǎn)說明。
(1)最好對于虛擬指針以及虛擬指針表格有一定了解。
不了解的話,你只能是記住我說的,但是不一定能理解很好。
(2)父類引用指向子類。方法調(diào)用的時(shí)候執(zhí)行的是子類的方法。
這個(gè)說法是有很多前提和意外的。
下面我舉一個(gè)例子
*/
b.display();
//****************原來文章表述有錯(cuò)誤開始***********************
// 下面調(diào)用會(huì)出錯(cuò)的()
//t.display2();
//********************原文表述錯(cuò)誤結(jié)束*******************
//現(xiàn)在應(yīng)該改成下面的描述
//下面這行應(yīng)該改為b.display()
//這樣才能結(jié)合本文舉的例子。同時(shí)下面一行是可以運(yùn)行的。
//對于這樣的寫作失誤,作者表示鄭重道歉
//************************************************************
//應(yīng)該象下面那樣
((test)b).display2();
int temp1=b.ageOfBase;
// 下面調(diào)用會(huì)出錯(cuò)
//int temp2=t.ageOfTest;
//應(yīng)該向下面那樣
int temp2=((test)b).ageOfTest;
/*
現(xiàn)在解釋上面兩個(gè)會(huì)出錯(cuò)的原因,這個(gè)原因是動(dòng)態(tài)性的根本所在。
我盡力能解釋清楚一點(diǎn)。
**************關(guān)鍵一********************
因?yàn)楦割惡妥宇惖膶ο笤趦?nèi)存中的大小是不一樣的,當(dāng)然了
不同的對象本身就不可能是同一塊內(nèi)存地址的。
這個(gè)應(yīng)該沒有問題的吧,當(dāng)然了要是子類中只是簡單的
繼承而沒有都沒有做的話,可能是一樣的,但是在c++中
各家編譯器還有會(huì)有一點(diǎn)差異的,可能也會(huì)不一樣的。
***************關(guān)鍵二************************
引用本質(zhì)上是通過指針來實(shí)現(xiàn)的,更深入一點(diǎn)是引用是指向指針的指針,
而不同類型的指針?biāo)芾淼膬?nèi)存空間大小是不一樣的,這一點(diǎn)跟上面
聯(lián)系很緊的。注意這里是說指針管理的內(nèi)存而不是指針,我想大家都
知道指針只有4個(gè)字節(jié)長度的。這里我們可以簡單的說是變量的可見性
問題,因?yàn)樽兞侩m然存在但是并不一定是可見的。
***************關(guān)鍵三************************
多態(tài)性的關(guān)鍵是動(dòng)態(tài)綁定,說白了就是虛擬函數(shù)虛擬指針虛擬指針表
等幾個(gè)重要的概念。簡單講一下,這里很復(fù)雜的,但是每一個(gè)真正的
面向?qū)ο缶幊倘藛T必須花時(shí)間很好的理解這一點(diǎn)。java 中只有靜態(tài)函數(shù)
和虛擬函數(shù)兩種,c++中還有一種 非靜態(tài)非虛擬函數(shù)。所以java的動(dòng)態(tài)
綁定要容易一點(diǎn)的。 你可以不精確的這樣理解(因?yàn)榻忉尵_我也很懶,
可以寫很長的文章了),每次類編譯的時(shí)候都會(huì)生成一個(gè)虛擬函數(shù)表,
表里面保存自己類中所有的虛擬函數(shù)地址,同時(shí)要是這個(gè)類存在父類
(不管是extends class 還是implements interface)的話,同時(shí)他會(huì)把
從父類繼承來的虛擬函數(shù)表也繼承過來(這里我只是大概解釋,不是很準(zhǔn)確)。
這個(gè)地方請注意:
************************************************
要是子類沒有改寫父類繼承的方法,父類虛擬函數(shù)中對應(yīng)虛擬函數(shù)地址
被變成子類自己的虛擬函數(shù)地址;如果沒有改變則不需要改變繼承來的
虛擬函數(shù)表對應(yīng)函數(shù)的地址。
*************************************************
***************開始解釋************************
當(dāng)父類引用指向子類對象的時(shí)候,父類引用管理的內(nèi)存空間,
是要比子類真實(shí)的內(nèi)存空間小的。所以子類中比父類中多的
東西對于這個(gè)父類引用來說是不可見的。所以也就沒有辦法引用。
上面的那個(gè)變量引用和函數(shù)引用就是這樣的,因?yàn)楦割愔袥]有
變量ageOfTest和函數(shù)display2()的。但是我們可以知道父類指針
實(shí)際上是指向子類的,所以我們解決這個(gè)問題的方法就是:
強(qiáng)制轉(zhuǎn)換類型(java中叫造型)。
同時(shí)可能有人要問,子類中那個(gè)函數(shù)地址不是也在虛擬函數(shù)表中嗎?
很高興你問這樣的問題,但是父類引用看到的虛擬函數(shù)表是沒有
那個(gè)函數(shù)項(xiàng)目的,因?yàn)樗麑τ诟割愐媒^對是不可見。
對于另外一個(gè)虛擬函數(shù)調(diào)用,如果你看了說明很仔細(xì)的話,你現(xiàn)在一定
知道雖然是父類引用管理內(nèi)存范圍小,但是那個(gè)虛擬函數(shù)表,父類中有的,
但是由于函數(shù)被子類中改寫了,所以那個(gè)表中函數(shù)地址編程子類的拉,
當(dāng)然就是引用子類的方法了。
/****************重要補(bǔ)充************************
java中靜態(tài)函數(shù)是沒有動(dòng)態(tài)性,因?yàn)殪o態(tài)函數(shù)不能被繼承,也不能被
改寫為非靜態(tài)方法。因?yàn)殪o態(tài)就意味著類的所有實(shí)例共享一個(gè)實(shí)體。
**************************************************
*/
}
}
關(guān)于“JAVA中動(dòng)態(tài)性實(shí)例分析”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對“JAVA中動(dòng)態(tài)性實(shí)例分析”知識(shí)都有一定的了解,大家如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。