Java: how to initialize a child when a superconstructor needs a parameter

I have

class A { int var; public A(int x) { var = x; } } class B extends A { int var2; public B(int x, int y) { super(...); var2 = y; x = f(y); } } 

For subclass B, I need to calculate the value of x, which is used in constructor A. If I could freely move super below my x=f(y) , then I could pass the result to constructor A (super). But super should be the first line in constructor B.

Is there a way to initialize A with the correct value for the first time? What if A.var was final and I couldn’t go back and change it after construction?

Of course, I could put super(f(y)) , but I could imagine cases when it was difficult.

+6
source share
4 answers

Assuming var is private, and you need to set the value using a constructor (which seems to be the point of the question, otherwise there are many simple solutions), I would just do it with a static factory method.

 class B extends A { int var2; public static B createB(int x, int y) { x = f(y); return new B(x, y); } public B(x, y) { super(x); this.var2 = y; } } 

something like that. You have no choice, since an explicit constructor call should occur on the first line of the wrapper constructor.

+10
source

You can do it as follows:

 class B extends A { int var2; public B(int x, int y) { super(calculateX(y)); var2 = y; } private static int calculateX(int y) { return y; } } 

Calling a static method is the only thing you can do before calling the constructor of a superclass.

+2
source

An alternative to hvgotcodes, since it looks like you also want to set the variable A ...

 class B extends A { int var2; public B(int x, int y) { super(x); var2 = y; x = f(y); super.var = ...; } } 
0
source

Another approach could be to add a protected, parameterless constructor to A, which relies on lazy initialization:

 class A { int var; public A(int x) { var = x; } /** * Just use this constructor if you initialize var */ protected A(int x) { } } class B extends A { int var2; public B(int x, int y) { super(); var2 = y; var = f(y); } } 

But this is difficult to document, not very obvious for team members and should not be used for api.

0
source

Source: https://habr.com/ru/post/921999/


All Articles