这是一个关于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
等
如何才能最好地做到这一点,而不需要在子类的构造函数中“手动”分配所有这些字段?
您必须在基类构造函数或子类中为变量赋值。
您可以在子类中声明一个参数化构造函数来将值赋给超类中的变量
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;
}
}
除了手动复制之外,您不能。
Java 不是 JavaScript,其中对象是其他对象的原型,相反,在 Java 中,类是其他类的子类。
我现在想从现有的超类生成一个子类对象 物体
事实上不是,您将通过依赖
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
}
如果您确实无法更改超类,那么检查和修改成员变量值的唯一方法是使用反射。
您应该注意,如果 getter 和 setter 没有暴露给子类(即它们是
private
),那么就会出现一个问题:类的原始创建者是否希望您首先能够访问所包含的变量。您的作业会以不可预测/不受支持的方式改变家长的行为吗?
如果
SuperClass
是您自己设计的,那么您应该确保始终使用 getter 和 setter,以便您可以明确地与您的类定义正确的协议(交互方式)。此规则也适用于类构造函数的可见性。一般来说,类的每个成员变量都应该可以通过类构造函数进行初始化;该构造函数是否可见,或者将所有可能的参数公开给子类,或者由外部源分配,都是另一回事。
为了让 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;
}
}