淺談Java向下轉(zhuǎn)型的意義
一開始學(xué)習(xí) Java 時(shí)不重視向下轉(zhuǎn)型。一直搞不清楚向下轉(zhuǎn)型的意義和用途,不清楚其實(shí)就是不會,那開發(fā)的過程肯定也想不到用向下轉(zhuǎn)型。
其實(shí)向上轉(zhuǎn)型和向下轉(zhuǎn)型都是很重要的,可能我們平時(shí)見向上轉(zhuǎn)型多一點(diǎn),向上轉(zhuǎn)型也比較好理解。
但是向下轉(zhuǎn)型,會不會覺得很傻,我是要用子類實(shí)例對象,先是生成子類實(shí)例賦值給父類引用,在將父類引用向下強(qiáng)轉(zhuǎn)給子類
引用,這不是多此一舉嗎?我不向上轉(zhuǎn)型也不向下轉(zhuǎn)型,直接用子類實(shí)例就行了。
我開始學(xué)習(xí)Java時(shí)也是這么想的,這誤區(qū)導(dǎo)致我覺得向下轉(zhuǎn)型就是沒用的。
隨著技術(shù)的提升,我在看開源的項(xiàng)目學(xué)習(xí),發(fā)現(xiàn)很多地方都用了向下轉(zhuǎn)型的技術(shù),這就讓我重視了起來,想要重新來復(fù)習(xí)(學(xué)習(xí))這個(gè)知識點(diǎn)。也是搜索了許多博客文章,但都沒具體說明向下轉(zhuǎn)型,只是給了例子演示怎么使用,反而是向上轉(zhuǎn)型講了一堆(可能是我沒找到)。
這篇博客就是講向下轉(zhuǎn)型的,那我們就來學(xué)習(xí)下向下轉(zhuǎn)型,了解下這種特性的意義和使用場景
新建一個(gè)電子產(chǎn)品接口,如下:
public interface Electronics{
}
很簡單,什么方法都沒有。
新建一個(gè)Thinkpad筆記本類,并實(shí)現(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");
}
}
新建一個(gè)Mouse鼠標(biāo)類,并實(shí)現(xiàn)電子產(chǎn)品接口:
public class Mouse implements Electronics{
//鼠標(biāo)移動
public void move(){
System.out.println("move the mouse");
}
//鼠標(biāo)點(diǎn)擊
public void onClick(){
System.out.println("a click of the mouse");
}
}
新建一個(gè)Keyboard鍵盤類,并實(shí)現(xiàn)電子產(chǎn)品接口:
public class Keyboard implements Electronics{
//使用鍵盤輸入
public void input(){
System.out.println("using Keyboard input");
}
}
這里子類比較多,是為了更好的理解。每個(gè)類的方法的邏輯實(shí)現(xiàn)也很簡單。打印了一行信息
接下來,我們想象一個(gè)情景:我們?nèi)ド坛琴I電子產(chǎn)品,電子產(chǎn)品很多吧,比如筆記本電腦,鼠標(biāo),鍵盤,步步高點(diǎn)讀機(jī)哪里不會點(diǎn)哪里,我們用的手機(jī),等等,這些都屬于電子產(chǎn)品。電子產(chǎn)品是抽象的。好,那么我們決定買一臺Thinkpad,一個(gè)鼠標(biāo)和一個(gè)鍵盤。
這時(shí),我們需要一個(gè)購物車來裝這些電子產(chǎn)品吧。我們可以添加進(jìn)購物車,然后通過購物車還能知道存放的電子產(chǎn)品數(shù)量,能拿到對應(yīng)的電子產(chǎn)品。
那么,一個(gè)購物車類就出來了,如下:
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> 用了泛型的知識,至于為什么要用泛型?這個(gè)不做介紹了,泛型很重要的。
而我覺得比較疑惑的是為什么是放 Electronics 的泛型,而不是放Thinkpad,Mouse,Keyboard,Phone等?
那么如果是List<Thinkpad>,肯定是放不進(jìn)鼠標(biāo)Mouse的吧,難道要生成3個(gè)集合?這里是定義了3個(gè)電子產(chǎn)品類,但是我如果有100種電子產(chǎn)品呢,要定義100個(gè)集合?
這太可怕了。所以之前,我們寫了一個(gè)Electronics接口,提供了一個(gè)Electronics的標(biāo)準(zhǔn),然后讓每一個(gè)Electronics子類都去實(shí)現(xiàn)這個(gè)接口。
實(shí)際上這里又涉及到了向上轉(zhuǎn)型的知識點(diǎn),我們雖然在add 方法將子類實(shí)例傳了進(jìn)來存放,但子類實(shí)例在傳進(jìn)去的過程中也進(jìn)行了向上轉(zhuǎn)型
所以,此時(shí)購物車?yán)锎娣诺淖宇悓?shí)例對象,由于向上轉(zhuǎn)型成Electronics,已經(jīng)丟失了子類獨(dú)有的方法,以上述例子來分析,Thinkpad實(shí)例就是丟失了boot() 和program() 這兩個(gè)方法,而Mouse實(shí)例就是丟失了move()和onClick()這兩個(gè)方法
但是實(shí)際使用Thinkpad或Mouse或Keyboard時(shí),這種情況肯定不是我們想要的
接著我們寫一個(gè)測試類 Test 去測試購物車?yán)锏碾娮赢a(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){
//添加進(jìn)購物車
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鼠標(biāo)
Mouse mouse = (Mouse)shopcar.getListItem(MOUSE);
mouse.move();
mouse.onClick();
System.out.println("-------------------");
//開始測試Keyboard鍵盤
Keyboard keyboard = (Keyboard)shopcar.getListItem(KEYBOARD);
keyboard.input();
}
}
運(yùn)行截圖:

舉個(gè)例子分析就好
//開始測試thinkpad電腦 Thinkpad thinkpad = (Thinkpad)shopcar.getListItem(THINKPAD); thinkpad.boot(); thinkpad.program();
shopcar.getListItem(THINKPAD)這句代碼是獲取到Electronics類型的實(shí)例。不是Thinkpad的實(shí)例
通過向下轉(zhuǎn)型,賦值給子類引用
Thinkpad thinkpad = (Thinkpad)shopcar.getListItem(THINKPAD);
這樣子類實(shí)例又重新獲得了因?yàn)橄蛏限D(zhuǎn)型而丟失的方法(boot 和program)
總結(jié)一下吧,很多時(shí)候,我們需要把很多種類的實(shí)例對象,全部扔到一個(gè)集合。(這句話很重要)
在這個(gè)例子里就是把Thinkpad筆記本,Mouse鼠標(biāo),KeyBoard鍵盤等實(shí)例對象,全部扔到一個(gè)Shopcar購物車集合。
但是肯定不可能給他們每個(gè)種類都用一個(gè)獨(dú)立的集合去存放吧,這個(gè)時(shí)候我們應(yīng)該尋找到一個(gè)標(biāo)準(zhǔn),接口就是一個(gè)標(biāo)準(zhǔn)。這些都是各種電子產(chǎn)品,抽象成電子產(chǎn)品。然后一個(gè)Electronics接口就出來了。
在回到剛才,我們把很多種類的實(shí)例對象全部扔到一個(gè)集合?;蛟S這樣比較好理解:把很多種類的子類實(shí)例對象全部扔到存放父類實(shí)例的集合。
經(jīng)過了這個(gè)過程,子類實(shí)例已經(jīng)賦值給了父類引用(即完成了向上轉(zhuǎn)型),但很遺憾的丟失了子類擴(kuò)展的方法。
很好的是Java語言有個(gè)向下轉(zhuǎn)型的特性,讓我們可以重新獲得丟失的方法,即強(qiáng)轉(zhuǎn)回子類
所以我們需要用到子類實(shí)例的時(shí)候,就從那個(gè)父類集合里拿出來向下轉(zhuǎn)型就可以了,一樣可以使用子類實(shí)例對象
……
我在搜索java向下轉(zhuǎn)型的意義時(shí),得到一個(gè)比較好的答案是這樣的:
最大的用處是java的泛型編程,用處很大,Java的集合類都是這樣的。
而在Android開發(fā)中,我們在Layout文件夾,用xml寫的控件。為什么能在Activity等組件中通過 findViewById() 方法找到呢?為什么 findViewById(R.id.textview) 方法傳入TextView的id后,還要轉(zhuǎn)型為TextView呢?這就是 Java 向下轉(zhuǎn)型的一個(gè)應(yīng)用
到此這篇關(guān)于淺談Java向下轉(zhuǎn)型的意義的文章就介紹到這了,更多相關(guān)Java 向下轉(zhuǎn)型內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Bean?Searcher配合SpringBoot的使用詳解
這篇文章主要介紹了Bean?Searcher配合SpringBoot的使用,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-06-06
解決SpringCloud Gateway配置自定義路由404的坑
這篇文章主要介紹了解決SpringCloud Gateway配置自定義路由404的坑,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09
Java生成二維碼的兩種實(shí)現(xiàn)方式(基于Spring?Boot)
這篇文章主要給大家介紹了關(guān)于Java生成二維碼的兩種實(shí)現(xiàn)方式,文中的代碼基于Spring?Boot,本文基于JAVA環(huán)境,以SpringBoot框架為基礎(chǔ)開發(fā),文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-07-07
json-lib將json格式的字符串,轉(zhuǎn)化為java對象的實(shí)例
下面小編就為大家?guī)硪黄猨son-lib將json格式的字符串,轉(zhuǎn)化為java對象的實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-03-03
Java Scala實(shí)現(xiàn)數(shù)據(jù)庫增刪查改操作詳解
這篇文章主要介紹了Java Scala實(shí)現(xiàn)數(shù)據(jù)庫增刪查改操作,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2023-04-04
Java AOP實(shí)現(xiàn)自定義滑動窗口限流器方法詳解
這篇文章主要介紹了Java AOP實(shí)現(xiàn)自定義滑動窗口限流器方法,其中滑動窗口算法彌補(bǔ)了計(jì)數(shù)器算法的不足,滑動窗口算法把間隔時(shí)間劃分成更小的粒度,當(dāng)更小粒度的時(shí)間間隔過去后,把過去的間隔請求數(shù)減掉,再補(bǔ)充一個(gè)空的時(shí)間間隔,需要的朋友可以參考下2022-07-07
Java之?dāng)?shù)組在指定位置插入元素實(shí)現(xiàn)
本文主要介紹了Java之?dāng)?shù)組在指定位置插入元素實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-01-01
springBoot靜態(tài)資源加載不到,并且配置了也不生效問題及解決
這篇文章總結(jié)了一個(gè)在Spring Boot 2.6.x版本中,由于路徑匹配策略改變導(dǎo)致靜態(tài)資源無法加載的問題,并提供了解決方案:通過配置類或在配置文件中設(shè)置路徑匹配策略為AntPathMatcher,或者直接降級Spring Boot版本2025-02-02

