簡體   English   中英

為帶有父對象的子類編寫Java構造函數

[英]Writing Java constructor for child class that takes parent object

是否可以使用父對象實例化子對象? Length2類通過添加實例變量來擴展Length1。 常見問題,我試圖制作一個將Length1作為參數並將額外的ivar設置為0的副本構造函數,但仍然有人告訴我我無法從Legnth1轉換為Length2。 我想可能會發生一些隱式轉換...看看。

public class Length1 extends Length implements Comparable<Length1>{

    protected int miles;
    protected int yards;

    public Length1(){ //default constructor
        miles = 0;
        yards = 0;
    }

    public Length1(int m, int y){ //constructor
        miles = m;
        yards = y;
    }

    public void setYards(int x){
        yards = x;
    }
    public void setMiles(int x){
        miles = x;
    }
    public int getYards(){
        return yards;
    }
    public int getMiles(){
        return miles;
    }

...

public class Length2 extends Length1 {

    protected int feet;

    public Length2(){ //default constructor
        super(0,0);
        setFeet(0); 
    }
    public Length2(int m, int y, int f){ // constructor
        super(m,y); 
        setFeet(f); 
    }
    public Length2(Length1 x){ 
        super(x.miles,x.yards);
        setFeet(0); 
    }
    public void setFeet(int x){
        feet = x;
    }
    public int getFeet(){
        return feet;
    }

...

public class LengthTest{

    public static void main(String[] args) {
        Length1 a,b,c,d,e,f;
        Length2 g,h,i,j;

        a = new Length1(78,1610);
        b = new Length1(77,1694);
        c = new Length1();
        d = new Length1();

        g = new Length2(32,1022,1);
        h = new Length2(31,1700,2);
        i = new Length2();
        j = new Length2();


        j = c; //problem occurs here


    }

}

就像Leo所說的那樣,如果L1是L2的超類型,則意味着L2擁有所有L1,然后擁有所有L1。 因此,如果嘗試從L1創建L2,則會丟失信息。

我的回答是不,您不能不幸。 但是您可以嘗試使用某種方法(例如L2 = L2.valueOf(L1))將所有有用的信息從L1推送到L2,該方法將所有已知字段從L1復制到L2,而將丟失的字段留空。 您必須手動編寫此方法。 也許您可以節省一些時間,以便在L2中重用某些L1構造函數。

你不能那樣做。 Length2是一個Length1,因此您始終可以將Length2 對象分配給Length1引用( Length1 )。 您還可以將一個指向Length2對象的Length1引用分配給另一個聲明為Length2引用。 在這種情況下,您需要進行顯式轉換,因為編譯器在編譯時不知道Length1引用實際上是Length2 但是您嘗試做的事情是不可能的,因為Length1不是Length2

就像說Car extends Vehicle 您總是可以指向Car並說出Car

Car c = new Car();

總是可以的 您總是可以指向一個說出Vehicle

Vehicle v = new Car();

沒問題。 您在這里遇到的唯一問題是,如果您決定調用例如Car中不存在的CarprintLicensePlate()方法,該方法具有一種稱為printSpeed() 由於Car是車輛,因此您可以隨時致電:

c.printSpeed();
c.printLicensePlate();

v.printSpeed();

但您不能致電:

v.printLicensePlate();

即使您知道vCar 在使用強制轉換來轉換引用的情況下就是這種情況。 這是非法的:

c = v; // WRONG

因為在編譯時我們不知道c到底是什么,因為new Car()僅在運行時發生。 因此,您通過執行以下操作告訴編譯器“相信我,這確實是一輛Car ”:

c = (Car) v;

但是您所做的是這樣的:

Car c = new Vehicle(); // WRONG

您指着一輛通用Vehicle然后說Car 盡管Car始終是Vehicle ,但Vehicle可能不是汽車。 (使用c引用,編譯器認為您可以合法地調用c.printLicensePlate() ,但是在運行時,您找到的對象沒有此類方法。因此,即使您可以通過強制轉換引用將其傳遞給編譯器,也不會工作,並且會在運行時產生ClassCastException 。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM