java向上轉型,java向上轉型有什麼用

本文目錄一覽:

在java裡面的向上轉型和向下轉型的具體好處在哪裡?

java裡面的向上轉型和向下轉型的具體好處如下:

1.轉型是在繼承的基礎上而言的,繼承是面向對象語言中,代碼復用的一種機制,通過繼承,子類可以復用父類的功能,如果父類不能滿足當前子類的需求,則子類可以重寫父類中的方法來加以擴展。

2.向上轉型:子類引用的對象轉換為父類類型稱為向上轉型。通俗地說就是是將子類對象轉為父類對象。此處父類對象可以是介面

向上轉型時,父類指向子類引用對象會遺失除與父類對象共有的其他方法,也就是在轉型過程中,子類的新有的方法都會遺失掉,在編譯時,系統會提供找不到方法的錯誤。實例如下:

public class Animal {

         public void eat(){

                   System.out.println(“animal eatting…”);

         }

}

class Bird extends Animal{

         public void eat(){

                   System.out.println(“bird eatting…”);

         }

         public void fly(){

                   System.out.println(“bird flying…”);

         }

}

class Main{      

         public static void main(String[] args) {

                   Animal b=new Bird(); //向上轉型

                   b.eat();

         b.fly();  //此處提示在Animal中沒有定義fly方法。

在java 中,什麼叫向上轉型?

java 轉型問題其實並不複雜,只要記住一句話:父類引用指向子類對象。\x0d\x0a\x0d\x0a什麼叫父類引用指向子類對象,且聽我慢慢道來.\x0d\x0a\x0d\x0a從2個名詞開始說起:向上轉型(upcasting) 、向下轉型(downcasting).\x0d\x0a\x0d\x0a舉個例子:有2個類,Father是父類,Son類繼承自Father。\x0d\x0a\x0d\x0aFather f1 = new Son(); // 這就叫 upcasting (向上轉型)\x0d\x0a\x0d\x0a// 現在f1引用指向一個Son對象\x0d\x0a\x0d\x0aSon s1 = (Son)f1; // 這就叫 downcasting (向下轉型)\x0d\x0a\x0d\x0a// 現在f1還是指向Son對象\x0d\x0a\x0d\x0a第2個例子:\x0d\x0a\x0d\x0aFather f2 = new Father();\x0d\x0a\x0d\x0aSon s2 = (Son)f2; // 出錯,子類引用不能指向父類對象\x0d\x0a\x0d\x0a你或許會問,第1個例子中:Son s1 = (Son)f1;問什麼 是正確的呢。\x0d\x0a\x0d\x0a很簡單因為f1指向一個子類對象,Father f1 = new Son(); 子類s1引用當然可以指向子類對象了。\x0d\x0a\x0d\x0a而f2 被傳給了一個Father對象,Father f2 = new Father();子類s1引用不能指向父類對象。\x0d\x0a\x0d\x0a總結:\x0d\x0a\x0d\x0a1。父類引用指向子類對象,而子類引用不能指向父類對象。\x0d\x0a\x0d\x0a2。把子類對象直接賦給父類引用叫upcasting向上轉型,向上轉型不用強制轉換。\x0d\x0a\x0d\x0a 如:Father f1 = new Son();\x0d\x0a\x0d\x0a3。把指向子類對象的父類引用賦給子類引用叫向下轉型(downcasting),要強制轉換。\x0d\x0a\x0d\x0a 如:f1 就是一個指向子類對象的父類引用。把f1賦給子類引用s1即 Son s1 = (Son)f1;\x0d\x0a\x0d\x0a 其中f1前面的(Son)必須加上,進行強制轉換。\x0d\x0a\x0d\x0a一、向上轉型。\x0d\x0a通俗地講即是將子類對象轉為父類對象。此處父類對象可以是介面。\x0d\x0a\x0d\x0a1,向上轉型中的方法調用。\x0d\x0a\x0d\x0a看下面代碼:\x0d\x0a\x0d\x0a[java] view plaincopyprint?\x0d\x0apackage com.wensefu.others; \x0d\x0apublic class Animal { \x0d\x0a \x0d\x0a public void eat(){ \x0d\x0a System.out.println(“animal eatting…”); \x0d\x0a } \x0d\x0a} \x0d\x0aclass Bird extends Animal{ \x0d\x0a \x0d\x0a public void eat(){ \x0d\x0a System.out.println(“bird eatting…”); \x0d\x0a } \x0d\x0a \x0d\x0a public void fly(){ \x0d\x0a \x0d\x0a System.out.println(“bird flying…”); \x0d\x0a } \x0d\x0a} \x0d\x0aclass Main{ \x0d\x0a \x0d\x0a public static void main(String[] args) { \x0d\x0a \x0d\x0a Animal b=new Bird(); //向上轉型 \x0d\x0a b.eat(); \x0d\x0a //! error: b.fly(); b雖指向子類對象,但此時丟失fly()方法 \x0d\x0a dosleep(new Male()); \x0d\x0a dosleep(new Female()); \x0d\x0a } \x0d\x0a \x0d\x0a public static void dosleep(Human h) { \x0d\x0a h.sleep(); \x0d\x0a } \x0d\x0a} \x0d\x0a\x0d\x0a[java] view plaincopyprint?\x0d\x0apackage com.wensefu.others; \x0d\x0apublic class Human { \x0d\x0a public void sleep() { \x0d\x0a System.out.println(“Human sleep..”); \x0d\x0a } \x0d\x0a} \x0d\x0aclass Male extends Human { \x0d\x0a @Override \x0d\x0a public void sleep() { \x0d\x0a System.out.println(“Male sleep..”); \x0d\x0a } \x0d\x0a} \x0d\x0aclass Female extends Human { \x0d\x0a @Override \x0d\x0a public void sleep() { \x0d\x0a System.out.println(“Female sleep..”); \x0d\x0a } \x0d\x0a} \x0d\x0a\x0d\x0a注意這裡的向上轉型:\x0d\x0a Animal b=new Bird(); //向上轉型\x0d\x0a b.eat();\x0d\x0a\x0d\x0a此處將調用子類的eat()方法。原因:b實際指向的是Bird子類,故調用時會調用子類本身的方法。\x0d\x0a\x0d\x0a需要注意的是向上轉型時b會遺失除與父類對象共有的其他方法。如本例中的fly方法不再為b所有。\x0d\x0a\x0d\x0a2,向上轉型的好處。\x0d\x0a\x0d\x0a看上面的代碼,\x0d\x0a\x0d\x0a public static void dosleep(Human h) {\x0d\x0a h.sleep();\x0d\x0a }\x0d\x0a\x0d\x0a這裡以父類為參數,調有時用子類作為參數,就是利用了向上轉型。這樣使代碼變得簡潔。不然的話,\x0d\x0a如果dosleep以子類對象為參數,則有多少個子類就需要寫多少個函數。這也體現了JAVA的抽象編程思想。\x0d\x0a\x0d\x0a二、向下轉型。\x0d\x0a\x0d\x0a與向上轉型相反,即是把父類對象轉為子類對象。\x0d\x0a\x0d\x0a看下面代碼:\x0d\x0a\x0d\x0a[java] view plaincopyprint?\x0d\x0apackage com.wensefu.other1; \x0d\x0apublic class Girl { \x0d\x0a public void smile(){ \x0d\x0a System.out.println(“girl smile()…”); \x0d\x0a } \x0d\x0a} \x0d\x0aclass MMGirl extends Girl{ \x0d\x0a \x0d\x0a @Override \x0d\x0a public void smile() { \x0d\x0a \x0d\x0a System.out.println(“MMirl smile sounds sweet…”); \x0d\x0a } \x0d\x0a public void c(){ \x0d\x0a System.out.println(“MMirl c()…”); \x0d\x0a } \x0d\x0a} \x0d\x0aclass Main{ \x0d\x0a \x0d\x0a public static void main(String[] args) { \x0d\x0a \x0d\x0a Girl g1=new MMGirl(); //向上轉型 \x0d\x0a g1.smile(); \x0d\x0a \x0d\x0a MMGirl mmg=(MMGirl)g1; //向下轉型,編譯和運行皆不會出錯 \x0d\x0a mmg.smile(); \x0d\x0a mmg.c(); \x0d\x0a\x0d\x0aGirl g2=new Girl(); \x0d\x0a// MMGirl mmg1=(MMGirl)g2; //不安全的向下轉型,編譯無錯但會運行會出錯 \x0d\x0a// mmg1.smile(); \x0d\x0a// mmg1.c(); \x0d\x0a/*output: \x0d\x0a* CGirl smile sounds sweet… \x0d\x0a* CGirl smile sounds sweet… \x0d\x0a* CGirl c()… \x0d\x0a* Exception in thread “main” java.lang.ClassCastException: com.wensefu.other1.Girl \x0d\x0a* at com.wensefu.other1.Main.main(Girl.java:36) \x0d\x0a*/ \x0d\x0a if(g2 instanceof MMGirl){ \x0d\x0a MMGirl mmg1=(MMGirl)g2; \x0d\x0a mmg1.smile(); \x0d\x0a mmg1.c(); \x0d\x0a } \x0d\x0a \x0d\x0a } \x0d\x0a} \x0d\x0a\x0d\x0aGirl g1=new MMGirl(); //向上轉型\x0d\x0a g1.smile();\x0d\x0a MMGirl mmg=(MMGirl)g1; //向下轉型,編譯和運行皆不會出錯\x0d\x0a\x0d\x0a這裡的向下轉型是安全的。因為g1指向的是子類對象。\x0d\x0a\x0d\x0a而\x0d\x0aGirl g2=new Girl();\x0d\x0aMMGirl mmg1=(MMGirl)g2; //不安全的向下轉型,編譯無錯但會運行會出錯\x0d\x0a\x0d\x0a運行出錯:\x0d\x0a\x0d\x0aException in thread “main” java.lang.ClassCastException: com.wensefu.other1.Girl\x0d\x0a at com.wensefu.other1.Main.main(Girl.java:36)\x0d\x0a如代碼所示,可以通過instanceof來防止出現異常。

在java 中,什麼叫向上轉型

java 轉型問題其實並不複雜,只要記住一句話:父類引用指向子類對象。

什麼叫父類引用指向子類對象,且聽我慢慢道來.

從2個名詞開始說起:向上轉型(upcasting) 、向下轉型(downcasting).

舉個例子:有2個類,Father是父類,Son類繼承自Father。

Father f1 = new Son(); // 這就叫 upcasting (向上轉型)

// 現在f1引用指向一個Son對象

Son s1 = (Son)f1; // 這就叫 downcasting (向下轉型)

// 現在f1還是指向Son對象

第2個例子:

Father f2 = new Father();

Son s2 = (Son)f2; // 出錯,子類引用不能指向父類對象

你或許會問,第1個例子中:Son s1 = (Son)f1;問什麼 是正確的呢。

很簡單因為f1指向一個子類對象,Father f1 = new Son(); 子類s1引用當然可以指向子類對象了。

而f2 被傳給了一個Father對象,Father f2 = new Father();子類s1引用不能指向父類對象。

總結:

1。父類引用指向子類對象,而子類引用不能指向父類對象。

2。把子類對象直接賦給父類引用叫upcasting向上轉型,向上轉型不用強制轉換。

如:Father f1 = new Son();

3。把指向子類對象的父類引用賦給子類引用叫向下轉型(downcasting),要強制轉換。

如:f1 就是一個指向子類對象的父類引用。把f1賦給子類引用s1即 Son s1 = (Son)f1;

其中f1前面的(Son)必須加上,進行強制轉換。

一、向上轉型。

通俗地講即是將子類對象轉為父類對象。此處父類對象可以是介面。

1,向上轉型中的方法調用。

看下面代碼:

[java] view plaincopyprint?

package com.wensefu.others;

public class Animal {

public void eat(){

System.out.println(“animal eatting…”);

}

}

class Bird extends Animal{

public void eat(){

System.out.println(“bird eatting…”);

}

public void fly(){

System.out.println(“bird flying…”);

}

}

class Main{

public static void main(String[] args) {

Animal b=new Bird(); //向上轉型

b.eat();

//! error: b.fly(); b雖指向子類對象,但此時丟失fly()方法

dosleep(new Male());

dosleep(new Female());

}

public static void dosleep(Human h) {

h.sleep();

}

}

[java] view plaincopyprint?

package com.wensefu.others;

public class Human {

public void sleep() {

System.out.println(“Human sleep..”);

}

}

class Male extends Human {

@Override

public void sleep() {

System.out.println(“Male sleep..”);

}

}

class Female extends Human {

@Override

public void sleep() {

System.out.println(“Female sleep..”);

}

}

注意這裡的向上轉型:

Animal b=new Bird(); //向上轉型

b.eat();

此處將調用子類的eat()方法。原因:b實際指向的是Bird子類,故調用時會調用子類本身的方法。

需要注意的是向上轉型時b會遺失除與父類對象共有的其他方法。如本例中的fly方法不再為b所有。

2,向上轉型的好處。

看上面的代碼,

public static void dosleep(Human h) {

h.sleep();

}

這裡以父類為參數,調有時用子類作為參數,就是利用了向上轉型。這樣使代碼變得簡潔。不然的話,

如果dosleep以子類對象為參數,則有多少個子類就需要寫多少個函數。這也體現了JAVA的抽象編程思想。

二、向下轉型。

與向上轉型相反,即是把父類對象轉為子類對象。

看下面代碼:

[java] view plaincopyprint?

package com.wensefu.other1;

public class Girl {

public void smile(){

System.out.println(“girl smile()…”);

}

}

class MMGirl extends Girl{

@Override

public void smile() {

System.out.println(“MMirl smile sounds sweet…”);

}

public void c(){

System.out.println(“MMirl c()…”);

}

}

class Main{

public static void main(String[] args) {

Girl g1=new MMGirl(); //向上轉型

g1.smile();

MMGirl mmg=(MMGirl)g1; //向下轉型,編譯和運行皆不會出錯

mmg.smile();

mmg.c();

Girl g2=new Girl();

// MMGirl mmg1=(MMGirl)g2; //不安全的向下轉型,編譯無錯但會運行會出錯

// mmg1.smile();

// mmg1.c();

/*output:

* CGirl smile sounds sweet…

* CGirl smile sounds sweet…

* CGirl c()…

* Exception in thread “main” java.lang.ClassCastException: com.wensefu.other1.Girl

* at com.wensefu.other1.Main.main(Girl.java:36)

*/

if(g2 instanceof MMGirl){

MMGirl mmg1=(MMGirl)g2;

mmg1.smile();

mmg1.c();

}

}

}

Girl g1=new MMGirl(); //向上轉型

g1.smile();

MMGirl mmg=(MMGirl)g1; //向下轉型,編譯和運行皆不會出錯

這裡的向下轉型是安全的。因為g1指向的是子類對象。

Girl g2=new Girl();

MMGirl mmg1=(MMGirl)g2; //不安全的向下轉型,編譯無錯但會運行會出錯

運行出錯:

Exception in thread “main” java.lang.ClassCastException: com.wensefu.other1.Girl

at com.wensefu.other1.Main.main(Girl.java:36)

如代碼所示,可以通過instanceof來防止出現異常。

關於java的向上轉型

來自CSDN。通俗易懂。

我們在現實中常常這樣說:這個人會唱歌。在這裡,我們並不關心這個人是黑人還是白人,是成人還是小孩,也就是說我們更傾向於使用抽象概念「人」。再例如,麻雀是鳥類的一種(鳥類的子類),而鳥類則是動物中的一種(動物的子類)。我們現實中也經常這樣說:麻雀是鳥。這兩種說法實際上就是所謂的向上轉型,通俗地說就是子類轉型成父類。這也符合Java提倡的面向抽象編程思想。來看下面的代碼:

package a.b;

public class A {

public void a1() {

System.out.println(“Superclass”);

}

}

A的子類B:

package a.b;

public class B extends A {

public void a1() {

System.out.println(“Childrenclass”); //覆蓋父類方法

}

public void b1(){} //B類定義了自己的新方法

}

C類:

package a.b;

public class C {

public static void main(String[] args) {

A a = new B(); //向上轉型

a.a1();

}

}

如果運行C,輸出的是Superclass 還是Childrenclass?不是你原來預期的Superclass,而是Childrenclass。這是因為a實際上指向的是一個子類對象。當然,你不用擔心,Java虛擬機會自動準確地識別出究竟該調用哪個具體的方法。不過,由於向上轉型,a對象會遺失和父類不同的方法,例如b1()。有人可能會提出疑問:這不是多此一舉嗎?我們完全可以這樣寫:

B a = new B();

a.a1();

確實如此!但這樣就喪失了面向抽象的編程特色,降低了可擴展性。其實,不僅僅如此,向上轉型還可以減輕編程工作量。來看下面的顯示器類Monitor:

package a.b;

public class Monitor{

public void displayText() {}

public void displayGraphics() {}

}

液晶顯示器類LCDMonitor是Monitor的子類:

package a.b;

public class LCDMonitor extends Monitor {

public void displayText() {

System.out.println(“LCD display text”);

}

public void displayGraphics() {

System.out.println(“LCD display graphics”);

}

}

陰極射線管顯示器類CRTMonitor自然也是Monitor的子類:

package a.b;

public class CRTMonitor extends Monitor {

public void displayText() {

System.out.println(“CRT display text”);

}

public void displayGraphics() {

System.out.println(“CRT display graphics”);

}

}

等離子顯示器PlasmaMonitor也是Monitor的子類:

package a.b;

public class PlasmaMonitor extends Monitor {

public void displayText() {

System.out.println(“Plasma display text”);

}

public void displayGraphics() {

System.out.println(“Plasma display graphics”);

}

}

現在有一個MyMonitor類。假設沒有向上轉型,MyMonitor類代碼如下:

package a.b;

public class MyMonitor {

public static void main(String[] args) {

run(new LCDMonitor());

run(new CRTMonitor());

run(new PlasmaMonitor());

}

public static void run(LCDMonitor monitor) {

monitor.displayText();

monitor.displayGraphics();

}

public static void run(CRTMonitor monitor) {

monitor.displayText();

monitor.displayGraphics();

}

public static void run(PlasmaMonitor monitor) {

monitor.displayText();

monitor.displayGraphics();

}

}

可能你已經意識到上述代碼有很多重複代碼,而且也不易維護。有了向上轉型,代碼可以更為簡潔:

package a.b;

public class MyMonitor {

public static void main(String[] args) {

run(new LCDMonitor()); //向上轉型

run(new CRTMonitor()); //向上轉型

run(new PlasmaMonitor()); //向上轉型

}

public static void run(Monitor monitor) { //父類實例作為參數

monitor.displayText();

monitor.displayGraphics();

}

}

我們也可以採用介面的方式,例如:

package a.b;

public interface Monitor {

abstract void displayText();

abstract void displayGraphics();

}

將液晶顯示器類LCDMonitor稍作修改:

package a.b;

public class LCDMonitor implements Monitor {

public void displayText() {

System.out.println(“LCD display text”);

}

public void displayGraphics() {

System.out.println(“LCD display graphics”);

}

}

CRTMonitor、PlasmaMonitor類的修改方法與LCDMonitor類似,而MyMonitor可以不不作任何修改。

可以看出,向上轉型體現了類的多態性,增強了程序的簡潔性。

java中關於向上轉型的問題

RTTI機制

向上轉型的目的仍然是抽象。

比如

水果有顏色、味道。不同的水果有不同的顏色和味道。那麼當

水果

sg

=

new

橘子();

水果

sg1

=

new

蘋果();

sg.color();sg.taste();

sg1.color();sg1.taste();

sg,sg1都是水果實例的引用。但會調用不同的具體子類的方法。

其目地都是抽象。通過訪問父類或介面的方法(公共)達到一種對具體實現的封裝。對於介面的使用者來說,不需要關心實現細節。提高內聚,降低不必要的耦合。

再多說一句:注意轉型時帶來的

內存切片。

java向上轉型有什麼作用

java裡面的向上轉型和向下轉型的具體好處如下: 1.轉型是在繼承的基礎上而言的,繼承是面向對象語言中,代碼復用的一種機制,通過繼承,子類可以復用父類的功能,如果父類不能滿足當前子類的需求,則子類可以重寫父類中的方法來加以擴展。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/197647.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-03 20:05
下一篇 2024-12-03 20:05

相關推薦

  • java client.getacsresponse 編譯報錯解決方法

    java client.getacsresponse 編譯報錯是Java編程過程中常見的錯誤,常見的原因是代碼的語法錯誤、類庫依賴問題和編譯環境的配置問題。下面將從多個方面進行分析…

    編程 2025-04-29
  • Java JsonPath 效率優化指南

    本篇文章將深入探討Java JsonPath的效率問題,並提供一些優化方案。 一、JsonPath 簡介 JsonPath是一個可用於從JSON數據中獲取信息的庫。它提供了一種DS…

    編程 2025-04-29
  • Java Bean載入過程

    Java Bean載入過程涉及到類載入器、反射機制和Java虛擬機的執行過程。在本文中,將從這三個方面詳細闡述Java Bean載入的過程。 一、類載入器 類載入器是Java虛擬機…

    編程 2025-04-29
  • Java騰訊雲音視頻對接

    本文旨在從多個方面詳細闡述Java騰訊雲音視頻對接,提供完整的代碼示例。 一、騰訊雲音視頻介紹 騰訊雲音視頻服務(Cloud Tencent Real-Time Communica…

    編程 2025-04-29
  • Java Milvus SearchParam withoutFields用法介紹

    本文將詳細介紹Java Milvus SearchParam withoutFields的相關知識和用法。 一、什麼是Java Milvus SearchParam without…

    編程 2025-04-29
  • Java 8中某一周的周一

    Java 8是Java語言中的一個版本,於2014年3月18日發布。本文將從多個方面對Java 8中某一周的周一進行詳細的闡述。 一、數組處理 Java 8新特性之一是Stream…

    編程 2025-04-29
  • 為什麼用cmd運行Java時需要在文件內打開cmd為中心

    在Java開發中,我們經常會使用cmd在命令行窗口運行程序。然而,有時候我們會發現,在運行Java程序時,需要在文件內打開cmd為中心,這讓很多開發者感到疑惑,那麼,為什麼會出現這…

    編程 2025-04-29
  • Java判斷字元串是否存在多個

    本文將從以下幾個方面詳細闡述如何使用Java判斷一個字元串中是否存在多個指定字元: 一、字元串遍歷 字元串是Java編程中非常重要的一種數據類型。要判斷字元串中是否存在多個指定字元…

    編程 2025-04-29
  • VSCode為什麼無法運行Java

    解答:VSCode無法運行Java是因為默認情況下,VSCode並沒有集成Java運行環境,需要手動添加Java運行環境或安裝相關插件才能實現Java代碼的編寫、調試和運行。 一、…

    編程 2025-04-29
  • Java任務下發回滾系統的設計與實現

    本文將介紹一個Java任務下發回滾系統的設計與實現。該系統可以用於執行複雜的任務,包括可回滾的任務,及時恢復任務失敗前的狀態。系統使用Java語言進行開發,可以支持多種類型的任務。…

    編程 2025-04-29

發表回復

登錄後才能評論