user1981275
user1981275

Reputation: 13382

java initialize base class fields in subclass constructor

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?

Upvotes: 4

Views: 17600

Answers (5)

Bodad
Bodad

Reputation: 1

To take Ashishkumar's answer one step further,

Rather than creating a superclass constructor that takes individual parameters, you could create a "copy constructor" in the superclass. That way you won't have to pass individual superclass parameters into the subclass's "super()" constructor. Especially helpful if you have multiple subclasses.

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

Upvotes: 0

Ashishkumar Singh
Ashishkumar Singh

Reputation: 3600

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

Upvotes: 9

Mapsy
Mapsy

Reputation: 4272

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.

Upvotes: 0

davidxxx
davidxxx

Reputation: 131396

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
}

Upvotes: 0

Mordechai
Mordechai

Reputation: 16284

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.

Upvotes: 0

Related Questions