java initialize base class fields in subclass constructor

非 Y 不嫁゛ 提交于 2021-01-27 13:01:35

问题


This is a very basic question about subclasses in java, I still don't get it...

Suppose I have a superclass with three fields and with only the default constructor:

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

and I want to add a field x. I cannot change Superclass, so I make a subclass:

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

I now want to generate a Subclass object from an existing Superclass object:

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

such that I can still access sc.a, sc.b etc.

How can I best do this without assigning all these fields 'by hand' in the constructor of the subclass?


回答1:


You have to assign a value to the variables either in the base-class constructor or in the child class.

You can declare a parameterized constructor in sub-class to assign the value to a variable in the superclass

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

Or you can declare a parameterized constructor in BaseClass, and in child class, instead of calling super(), call that parametrized constructorsuper(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;
 }
}



回答2:


Other than copying by hand you can't.

Java is not JavaScript where objects are prototypes of other objects, instead in Java, classes subclass other classes.




回答3:


I now want to generate a Subclass object from an existing Superclass object

In fact no, you will instantiate a Subclass object by relying on the state of a Superclass object.

As you pass the SuperClass as parameter of the Subclass constructor, you just need to use fields of it to invoke the super constructor if you declare it :

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

Or if you have a super constructor with no arg :

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

Note that in Java using the private modifier for instance fields is strongly encouraged and you should access to field via public methods.

A cleaner way for your constructor would look like :

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
}



回答4:


If you truly cannot change the superclass, then the only way you can inspect and modify the values of the member variables is by using reflection.

You should note that if getters and setters aren't exposed to subclasses (i.e. they are private) then there's a question of whether the original creator of class wanted you to ever have access to the contained variables in the first place. Would your assignments change the behaviour of the parent in an unpredictable/unsupported way?

If the SuperClass is of your own design, then you should ensure that you always use getters and setters so that you may define the proper protocol (way to interact) with your class unambiguously. This rule also applies for the visibility of class constructors. Generally speaking, every member variable of a class should be possible to initialize via a class constructor; whether that constructor is visible, or exposes all of the possible parameters to subclasses or upon allocation by external sources, is a different story.



来源:https://stackoverflow.com/questions/51845169/java-initialize-base-class-fields-in-subclass-constructor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!