1. 程式人生 > >JavaSE(五)JAVA對象向上轉型和向下轉型

JavaSE(五)JAVA對象向上轉型和向下轉型

open 其他 解釋 編譯 -- 運行出錯 instance xtend args

今天做了一個測試的題目,發現自己還是很多問題沒有靜下心來做。很多問題是可以自己解決的但是自己一是沒有讀清題意,二是自己心裏太急躁了。所以這個要自己應以為鑒!

對象的轉型問題其實並不復雜,我們記住一句話:“父類引用指向子類對象”。

java中對象的轉型分為向上轉型和向下轉型

一、對象的向上轉型

  1.1、定義

    子類引用的對象轉換為父類類型稱為向上轉型。通俗地說就是是將子類對象轉為父類對象。此處父類對象可以是接口

  1.2、解釋

    比如說我有兩個類,一個是父類Animal,另一個是Bird類為子類。

    Animal b = new Bird();

    這就是upcasting,向上轉型。這時b就是執行以惡搞Bird對象。

  1.3、實例

 

技術分享
package com.zyh.test;

public class Animal {
    public void eat(){
        System.out.println("animal eating....");
    }
}
class Bird extends Animal{
    public void eat(){
        System.out.println("Bird eating...");
    }
    public void fly(){
        System.out.println("Bird flying...");
    }
}
class Main{
    public static void main(String[] args){
        Animal b1 = new Bird();
        b1.eat();
//        b1.fly();  b雖然指向子類對象,但此時丟失了fly方法
        doSleep(new Male());
        doSleep(new Female());
        
    }
    public static void doSleep(Human h){
        h.sleep();
    }
}
Animal.java 技術分享
package com.zyh.test;

public class Animal {
    public void eat(){
        System.out.println("animal eating....");
    }
}
class Bird extends Animal{
    public void eat(){
        System.out.println("Bird eating...");
    }
    public void fly(){
        System.out.println("Bird flying...");
    }
}
class Main{
    public static void main(String[] args){
        Animal b1 = new Bird();
        b1.eat();
//        b1.fly();  b雖然指向子類對象,但此時丟失了fly方法
        doSleep(new Male());
        doSleep(new Female());
        
    }
    public static void doSleep(Human h){
        h.sleep();
    }
}
Huamn

  註意:

    這裏的向上轉型:

      Animal b = new Bird();

       b.eat();

    這裏調用的eat方法是子類的。因為b實際指向的是Bird子類,故調用時會調用子類本身的方法。

    要記住向上轉型時父類的引用會遺失除與父類共有的其他方法。在上面的例子中b不能調用fly方法。

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

  1.4、向上轉型的優點 

    public static void dosleep(Human h) {
    h.sleep();
      }

    這裏以父類為參數,調有時用子類作為參數,就是利用了向上轉型。這樣使代碼變得簡潔。不然的話,
    如果dosleep以子類對象為參數,則有多少個子類就需要寫多少個函數。這也體現了JAVA的抽象編程思想。

二、對象的向下轉型

  1.1、定義

    父類引用的對象轉換為子類類型成為向下轉型

  1.2、解釋

    Son s = (Son)f1;

    這就是downcasting,向下轉型。

  1.3、實例

package com.zyh.test;

public class Person {
    public void play(){
        System.out.println("Person play...");
    }
}
class Boy extends Person{
    public void play(){
        System.out.println("boy play...");
    }
    public void run(){
        System.out.println("run play...");
    }
}
class RunMain{
    public static void main(String[] args){
        Person b = new Boy();//向上轉型
        b.play();
        System.out.println("-------------------------");
        Boy b1 =(Boy)b;//向下轉型
        b1.play();
        b1.run();
        
    }
}

  結果:

    技術分享

  在這個程序中       

    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)

  所以向下轉型過程中要註意的是:     

    情況一:如果父類引用的對象如果引用的是指向的子類對象,那麽在向下轉型的過程中是安全的。也就是編譯是不會出錯誤的。

    情況二:如果父類引用的對象是父類本身,那麽在向下轉型的過程中是不安全的,編譯不會出錯,但是運行時會出現java.lang.ClassCastException錯誤。它可以使用instanceof來避免出錯此類錯誤。

 三、總結

1、父類引用可以指向子類對象,子類引用不能指向父類對象。

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

   如Father father = new Son();

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

   如father就是一個指向子類對象的父類引用,把father賦給子類引用son 即Son son =(Son)father;

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

4、upcasting 會丟失子類特有的方法,但是子類overriding 父類的方法,子類方法有效

5、向上轉型的作用,減少重復代碼,父類為參數,調有時用子類作為參數,就是利用了向上轉型。這樣使代碼變得簡潔。體現了JAVA的抽象編程思想。

JavaSE(五)JAVA對象向上轉型和向下轉型