簡體   English   中英

在Java中,我可以使子類的實例“基於”超類的實例嗎?

[英]In Java, can I make an instance of a subclass “based on” an instance of the superclass?

假設我有一個Child類,它擴展了另一個類Parent

public class Parent {
    private String value;
    public Parent() { }
    public String getValue() { return this.value; }
    public void setValue(String value) { this.value = value; }
}

public class Child extends Parent {
    private String anotherValue;
    public Child() { super(); }
    public String getAnotherValue() { return this.anotherValue; }
    public void setAnotherValue() { this.anotherValue = anotherValue; }
}

現在,對於任何實例parent類的Parent ,並希望構建一個實例child類的Child ,使得對象child擴展對象parent ,即,在這種情況下, child.getValue().equals(parent.getValue())

一種方法是將構造函數添加到Child ,如下所示:

    public Child(Parent parent) {
        this.setValue(parent.getValue());
    }

這樣就可以完成工作,但是如果超類更復雜,並且隨着超類隨着時間的推移而發展,則該構造函數應該不斷進行更新(可能會被遺忘),或多或少會帶來災難性的后果,這可能是挑剔的。

也可以通過反射來完成,這可能是一個過大的殺傷力。

因此, 我想知道是否有Java原生方法可以做到這一點:創建子類的實例,並將實例的所有屬性復制為超類。 從某種意義上講,它是鑄造的逆向。

不, 沒有內置支持可以自動執行。 當您要復制字段值時,常見的模式是同時為ParentChild類創建復制構造函數

public class Parent {
    public int a;
    public String s;

    public Parent(Parent src) {
        this.a = src.a;
        this.s = src.s;
    }

    // +init-constructor
}

public class Child extends Parent {
    public double d;

    public Child(Child src) {
        super(src);
        this.d = src.d;
    }

    // +init-constructor
}

編輯

如果您只想從Parent類的Parent類中復制字段,則可以添加另一個僅復制父字段的復制構造器:

public class Child extends Parent {
    // +fields

    // +copy-constructor Child(Child src)

    public Child(Parent src) {
        super(src);
    }

    // +init-constructor
}

因此,將根據實例的類型選擇合適的構造函數。

Parent p = new Parent(1, "a");
Child c = new Child(1, "a", 2.0);

Child pCopy = new Child(p);
Child cCopy = new Child(c);

注意,如果您只想從子級復制父級字段,也可以顯式將子級實例上載到父級類型:

Child c = new Child(1, "a", 2.0);
Child  pCopy  = new Child((Parent) c);

如果您要將字段復制到已經構造的子對象中,我將執行類似@KarlNicholas的答復。

“我想知道是否有任何Java本機方法可以做到這一點:創建子類的實例並將該實例的所有屬性復制為超類”

什么都沒想到,但是您應該對自己想做的事情再加一點思考。 您可以在Parent中添加副本構造函數或使用克隆。

class Parent {
    String type;
    public Parent(Parent p) { this.type = p.type; }
}

class Child extends Parent {
    public Child(Parent p) { super(p); }
}

或者您可以在Child中創建一個靜態newInstance()方法

class Parent {
    String type;
    public copyInstance(Parent p) { this.type = p.type; }
}

class Child extends Parent {
    static Child newInstance(Parent p) { Child c = new Child(); c.copyInstance(p); return c; }
 }

或其他類似的東西。 簡而言之,我不得不問你為什么要讓Child知道Parent

是的,這是Java的缺點。 基本上,我們在這里談論克隆。 Java沒有內置在語言中的健壯的對象克隆機制。 您必須使用序列化/反序列化之類的技巧。

您可以根據自己的情況做些什么:

class Child {
 private Parent parent;

public Child(Parent p) {
 // reference - carefully! If Parent were immutable, this would be safe, otherwise, you need a copy constructor
 this.parent = p;
}
}

暫無
暫無

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

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