Java初始化子类构造函数中的基类字段

时间:2018-08-14 15:41:13

标签: java oop constructor subclass superclass

这是有关Java子类的一个非常基本的问题,我仍然不明白...

假设我有一个具有三个字段且仅具有默认构造函数的超类:

public class Superclass {
    public int a;
    public int b;
    public int c;
}

,我想添加一个字段x。我无法更改Superclass,所以我创建了一个子类:

public class Subclass extends Superclass {
    public int x;
    public Subclass(Superclass s) {
        super();
        // what to do??
    }
}

我现在想从现有的Subclass对象中生成一个Superclass对象:

Superclass s = new Superclass();
s.a = "a";
s.b = "b";
Subclass sc = new Subclass(s);
sc.x = "x";

这样我仍然可以访问sc.asc.b等。

如何最好地做到这一点,而不必在子类的构造函数中手动分配所有这些字段?

4 个答案:

答案 0 :(得分:3)

您必须在基类构造函数或子类中为变量分配一个值。

您可以在子类中声明参数化的构造函数,以将值分配给超类中的变量

class Subclass extends Superclass {
public int x;
public Subclass(int a,int b, int c,int x) {
    super();
    this.x = x;
    this.a=a;
    this.b=b;
    this.c=c;
 }
}

或者您可以在BaseClass和子类中声明参数化的构造函数,而不是调用super(),而是调用该参数化的构造函数super(a,b,c)

class Superclass {
public int a;
public int b;
public int c;

public Superclass(int a, int b, int c) {
    this.a = a;
    this.b = b;
    this.c = c;
 }   
}

class Subclass extends Superclass {
public int x;

public Subclass(int a,int b, int c,int x) {
    super(a,b,c);
    this.x = x;
 }
}

答案 1 :(得分:0)

除了手动复制外,您不能。

Java不是JavaScript,其中对象是其他对象的原型,而在Java中,类是其他类的子类。

答案 2 :(得分:0)

  

我现在想从现有的超类生成子类对象   对象

实际上,不会,您将依靠Subclass对象的状态来实例化Superclass对象。

在将SuperClass作为Subclass构造函数的参数传递时,只需声明它的字段即可调用超级构造函数:

public Subclass(Superclass s) {
    super(s.a, s.b, s.c); // constructor  may simplify
}

或者如果您有一个没有arg的超级构造函数:

public Subclass(Superclass s) { 
    a = s.a;
    b = s.b;
    c = s.c;
}

请注意,在Java中,强烈建议将private修饰符用于实例字段,并且您应通过public方法访问该字段。

为您的构造函数提供的更简洁的方法如下:

public SuperClass(int a, int b, int c) {
    this.a = a;
    this.b = b;
    this.c = c;
}

public Subclass(Superclass s) {
    super(s.getA(), s.getB(), s.getC()); // constructor  may simplify
}

答案 3 :(得分:0)

如果您确实无法更改超类,那么检查和修改成员变量值的唯一方法是使用reflection

您应该注意,如果getter和setter不暴露于子类(即它们是private),那么就会有一个问题,即类的原始创建者是否希望您能够访问第一名。您的作业会以一种无法预测/不受支持的方式改变父母的行为吗?

如果SuperClass是您自己设计的,则应确保始终使用getter和setter,以便可以与类明确定义正确的协议(交互方式)。此规则也适用于类构造函数的可见性。一般而言,类的每个成员变量都应该可以通过类构造函数进行初始化。究竟该构造函数是否可见,还是将所有可能的参数公开给子类还是由外部资源分配,都是另一回事。