java在子类构造函数中初始化基类字段

问题描述 投票:0回答:5

这是一个关于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.a
sc.b

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

java oop constructor subclass superclass
5个回答
9
投票

您必须在基类构造函数或子类中为变量赋值。

您可以在子类中声明一个参数化构造函数来将值赋给超类中的变量

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;
 }
}

0
投票

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

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


0
投票

我现在想从现有的超类生成一个子类对象 物体

事实上不是,您将通过依赖

Subclass
对象的状态来实例化
Superclass
对象。

当您将

SuperClass
作为
Subclass
构造函数的参数传递时,如果您声明它,则只需使用它的字段来调用超级构造函数:

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

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

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
}

0
投票

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

您应该注意,如果 getter 和 setter 没有暴露给子类(即它们是

private
),那么就会出现一个问题:类的原始创建者是否希望您首先能够访问所包含的变量。您的作业会以不可预测/不受支持的方式改变家长的行为吗?

如果

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


0
投票

为了让 Ashishkumar 的答案更进一步,

您可以在超类中创建一个“复制构造函数”,而不是创建一个采用单独参数的超类构造函数。 这样,您就不必将各个超类参数传递到子类的“super()”构造函数中。 如果您有多个子类,则特别有帮助。

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

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

        
class Subclass extends Superclass {
    public int x;
    
    public Subclass(Superclass superclass, int x) {
        super(superClass);
        this.x = x;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.