您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關(guān)關(guān)于Java向下轉(zhuǎn)型的介紹,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
一開始學(xué)習(xí) Java 時不重視向下轉(zhuǎn)型。一直搞不清楚向下轉(zhuǎn)型的意義和用途,不清楚其實就是不會,那開發(fā)的過程肯定也想不到用向下轉(zhuǎn)型。
其實向上轉(zhuǎn)型和向下轉(zhuǎn)型都是很重要的,可能我們平時見向上轉(zhuǎn)型多一點,向上轉(zhuǎn)型也比較好理解。
但是向下轉(zhuǎn)型,會不會覺得很傻,我是要用子類實例對象,先是生成子類實例賦值給父類引用,在將父類引用向下強轉(zhuǎn)給子類
引用,這不是多此一舉嗎?我不向上轉(zhuǎn)型也不向下轉(zhuǎn)型,直接用子類實例就行了。
我開始學(xué)習(xí)Java時也是這么想的,這誤區(qū)導(dǎo)致我覺得向下轉(zhuǎn)型就是沒用的。
隨著技術(shù)的提升,我在看開源的項目學(xué)習(xí),發(fā)現(xiàn)很多地方都用了向下轉(zhuǎn)型的技術(shù),這就讓我重視了起來,想要重新來復(fù)習(xí)(學(xué)習(xí))這個知識點。也是搜索了許多博客文章,但都沒具體說明向下轉(zhuǎn)型,只是給了例子演示怎么使用,反而是向上轉(zhuǎn)型講了一堆(可能是我沒找到)。
這篇博客就是講向下轉(zhuǎn)型的,那我們就來學(xué)習(xí)下向下轉(zhuǎn)型,了解下這種特性的意義和使用場景
新建一個電子產(chǎn)品接口,如下:
public interface Electronics{ }
很簡單,什么方法都沒有。
新建一個Thinkpad筆記本類,并實現(xiàn)電子產(chǎn)品接口:
public class Thinkpad implements Electronics{ //Thinkpad引導(dǎo)方法 public void boot(){ System.out.println("welcome,I am Thinkpad"); } //使用Thinkpad編程 public void program(){ System.out.println("using Thinkpad program"); } }
新建一個Mouse鼠標類,并實現(xiàn)電子產(chǎn)品接口:
public class Mouse implements Electronics{ //鼠標移動 public void move(){ System.out.println("move the mouse"); } //鼠標點擊 public void onClick(){ System.out.println("a click of the mouse"); } }
新建一個Keyboard鍵盤類,并實現(xiàn)電子產(chǎn)品接口:
public class Keyboard implements Electronics{ //使用鍵盤輸入 public void input(){ System.out.println("using Keyboard input"); } }
這里子類比較多,是為了更好的理解。每個類的方法的邏輯實現(xiàn)也很簡單。打印了一行信息
接下來,我們想象一個情景:我們?nèi)ド坛琴I電子產(chǎn)品,電子產(chǎn)品很多吧,比如筆記本電腦,鼠標,鍵盤,步步高點讀機哪里不會點哪里,我們用的手機,等等,這些都屬于電子產(chǎn)品。電子產(chǎn)品是抽象的。好,那么我們決定買一臺Thinkpad,一個鼠標和一個鍵盤。
這時,我們需要一個購物車來裝這些電子產(chǎn)品吧。我們可以添加進購物車,然后通過購物車還能知道存放的電子產(chǎn)品數(shù)量,能拿到對應(yīng)的電子產(chǎn)品。
那么,一個購物車類就出來了,如下:
import java.util.ArrayList; import java.util.List; public class ShopCar{ private List<Electronics> mlist = new ArrayList<Electronics>(); public void add(Electronics electronics){ mlist.add(electronics); } public int getSize(){ return mlist.size(); } public Electronics getListItem(int position){ return mlist.get(position); } }
List 集合是用來存放電子產(chǎn)品的,add 方法用來添加電子產(chǎn)品到購物車,getSize 方法用來獲取存放的電子產(chǎn)品數(shù)量,getListItem 方法用來獲取相應(yīng)的電子產(chǎn)品。
可以看到 List<Electronics> 用了泛型的知識,至于為什么要用泛型?這個不做介紹了,泛型很重要的。
而我覺得比較疑惑的是為什么是放 Electronics 的泛型,而不是放Thinkpad,Mouse,Keyboard,Phone等?
那么如果是List<Thinkpad>,肯定是放不進鼠標Mouse的吧,難道要生成3個集合?這里是定義了3個電子產(chǎn)品類,但是我如果有100種電子產(chǎn)品呢,要定義100個集合?
這太可怕了。所以之前,我們寫了一個Electronics接口,提供了一個Electronics的標準,然后讓每一個Electronics子類都去實現(xiàn)這個接口。
實際上這里又涉及到了向上轉(zhuǎn)型的知識點,我們雖然在add 方法將子類實例傳了進來存放,但子類實例在傳進去的過程中也進行了向上轉(zhuǎn)型
所以,此時購物車里存放的子類實例對象,由于向上轉(zhuǎn)型成Electronics,已經(jīng)丟失了子類獨有的方法,以上述例子來分析,Thinkpad實例就是丟失了boot() 和program() 這兩個方法,而Mouse實例就是丟失了move()和onClick()這兩個方法
但是實際使用Thinkpad或Mouse或Keyboard時,這種情況肯定不是我們想要的
接著我們寫一個測試類 Test 去測試購物車里的電子產(chǎn)品。
測試類 Test 如下:
public class Test{ public static final int THINKPAD = 0; public static final int MOUSE = 1; public static final int KEYBOARD = 2; public static void main(String[] args){ //添加進購物車 ShopCar shopcar = new ShopCar(); shopcar.add(new Thinkpad()); shopcar.add(new Mouse()); shopcar.add(new Keyboard()); //獲取大小 System.out.println("購物車存放的電子產(chǎn)品數(shù)量為 ——> "+shopcar.getSize()); //開始測試thinkpad電腦 Thinkpad thinkpad = (Thinkpad)shopcar.getListItem(THINKPAD); thinkpad.boot(); thinkpad.program(); System.out.println("-------------------"); //開始測試Mouse鼠標 Mouse mouse = (Mouse)shopcar.getListItem(MOUSE); mouse.move(); mouse.onClick(); System.out.println("-------------------"); //開始測試Keyboard鍵盤 Keyboard keyboard = (Keyboard)shopcar.getListItem(KEYBOARD); keyboard.input(); } }
運行截圖:
舉個例子分析就好
//開始測試thinkpad電腦 Thinkpad thinkpad = (Thinkpad)shopcar.getListItem(THINKPAD); thinkpad.boot(); thinkpad.program();
shopcar.getListItem(THINKPAD)這句代碼是獲取到Electronics類型的實例。不是Thinkpad的實例
通過向下轉(zhuǎn)型,賦值給子類引用
Thinkpad thinkpad = (Thinkpad)shopcar.getListItem(THINKPAD);
這樣子類實例又重新獲得了因為向上轉(zhuǎn)型而丟失的方法(boot 和program)
總結(jié)一下吧,很多時候,我們需要把很多種類的實例對象,全部扔到一個集合。(這句話很重要)
在這個例子里就是把Thinkpad筆記本,Mouse鼠標,KeyBoard鍵盤等實例對象,全部扔到一個Shopcar購物車集合。
但是肯定不可能給他們每個種類都用一個獨立的集合去存放吧,這個時候我們應(yīng)該尋找到一個標準,接口就是一個標準。這些都是各種電子產(chǎn)品,抽象成電子產(chǎn)品。然后一個Electronics接口就出來了。
在回到剛才,我們把很多種類的實例對象全部扔到一個集合?;蛟S這樣比較好理解:把很多種類的子類實例對象全部扔到存放父類實例的集合。
經(jīng)過了這個過程,子類實例已經(jīng)賦值給了父類引用(即完成了向上轉(zhuǎn)型),但很遺憾的丟失了子類擴展的方法。
很好的是Java語言有個向下轉(zhuǎn)型的特性,讓我們可以重新獲得丟失的方法,即強轉(zhuǎn)回子類
所以我們需要用到子類實例的時候,就從那個父類集合里拿出來向下轉(zhuǎn)型就可以了,一樣可以使用子類實例對象
……
我在搜索java向下轉(zhuǎn)型的意義時,得到一個比較好的答案是這樣的:
最大的用處是java的泛型編程,用處很大,Java的集合類都是這樣的。
而在Android開發(fā)中,我們在Layout文件夾,用xml寫的控件。為什么能在Activity等組件中通過 findViewById() 方法找到呢?為什么 findViewById(R.id.textview) 方法傳入TextView的id后,還要轉(zhuǎn)型為TextView呢?這就是 Java 向下轉(zhuǎn)型的一個應(yīng)用
關(guān)于關(guān)于Java向下轉(zhuǎn)型的介紹就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。