Reputation: 27
public class A {
final int x;
public A(int x) {
if ( this instanceof B ) {
if(x > 5)
this.x = x;
else
this.x = 0;
} else {
this.x = 0;
}
}
}
public class B extends A {
public B(int x) {
super(x);
}
}
I want to put the if in the class B to avoid instanceof ( because i have more sub classes and the x value depends on the subClass ), but when i do that i get compiler error: Constructor call must be the first statement in a constructor!
Can you help me avoid instanceof?
Upvotes: 1
Views: 664
Reputation: 10653
There are two ways we can initialize constants, first one is to initialize them in place on the same line as in the answer by Adam, second is to use constructors, which you're trying to implement.
Using inline initialization is generally more flexible because we are not bound to the rules of the constructor, like this(...)
or super(...)
call should be the first in the constructor. However if you do want to use constructor for the purpose you can use method containing logic as inline call as argument to the this(...) or super(...)
. This method should be static
as the instance of the class doesn't exist yet as we're in constructor. Following is a simple solution for the same.
class A {
final int x;
public A(int x) {
this.x = 0;
}
}
class B extends A {
public B(int x) {
super(getValueForX(x));
}
private static int getValueForX(int x) {
return x > 5 ? x : 0;
}
}
Upvotes: 1
Reputation: 30578
Just create an abstract
method in A
and implement it in your derived classes like this:
public abstract class A {
final int x;
abstract int calculateX(int x);
public A(int x) {
this.x = calculateX(x);
}
}
public class B extends A {
@Override
int calculateX(int x) {
return x + 1;
}
public B(int x) {
super(x);
}
}
Upvotes: 0