![](/img/trans.png)
[英]In Java, how do I make instance variables of a subclass have the type of the subclass, rather than of the superclass?
[英]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原生方法可以做到這一點:創建子類的實例,並將實例的所有屬性復制為超類。 從某種意義上講,它是鑄造的逆向。
不, 沒有內置支持可以自動執行。 當您要復制字段值時,常見的模式是同時為Parent
和Child
類創建復制構造函數 :
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.