在Java中,我可以“基于”超类的实例创建子类的实例吗?

时间:2017-06-28 16:21:14

标签: java inheritance

假设我有一个类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本地方法可以做到这一点:创建子类的实例并复制超类的实例的所有属性。它在某种程度上是反向的铸造。

3 个答案:

答案 0 :(得分:1)

不,有没有内置支持自动执行此操作。如果要复制字段值,常见的模式是为ParentChild类创建 copy-constructors

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复制字段,我会添加另一个只复制父字段的复制构造函数:

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时所看到的内容。

答案 1 :(得分:0)

“我想知道是否有任何Java本地方法可以做到这一点:创建子类的实例并复制超类”

的实例的所有属性

没有什么可以想到的,但你应该更加想想你要做的事情。您可以在Parent中添加复制构造函数或使用clone。

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

答案 2 :(得分:0)

是的,这是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;
}
}