Reputation: 375
I'm building a Challenge24Solver
class in Java. The logic itself works and finds the solutions as would be expected (with an arbitrary number of arguments). Anyway that part of the projects is works as I expect.
The question comes from problems with the representation of the solutions. It's fair to say that I've completed this project in Python and decided to attempt in Java as a sort of introduction, which may be the problem, that I'm trying to do this too like Python.
Here are some of my classes:
abstract class Operation { \\ Basic operation class
static String token;
abstract public double operate (double x, double y);
}
class AddOp extends Operation {
static String token = "+";
public double operate (double x, double y) {
return x+y;
}
}
//other operation classes SubOp, MulOp, DivOp
class Challenge24Step { // represents one step in a solution
Operation operator;
double x, y; //operands
double value; //the value of the step (x operator y)
public Challenge24Step (Operation operator, double x, double y) {
this.operator = operator;
// constructor code;
}
public String toString () {
return String.format("%s %s %s = %s", this.x, this.operator.token, this.y,
this.value);
}
}
The problem is that it still gets token from the Operation class: "null"
I understand that this is probably because operator is declared as Operation, but I don't understand why it doesn't go through standard inheritance: instance, class, each superclass
How would I rearrange the script so that the more specific operation classes' tokens are used?
Upvotes: 4
Views: 119
Reputation: 726509
You cannot make token
static in the base class, because then there would be a single token per all inherited classes. You need to make it an instance variable. You cannot even put it in a static method, because static
methods in Java are not overridable.
In Java, variables are not overridable. If you inherit a class and add a variable by the same name, the variable in the derived class will hide, not override the one in the base class.
To fix this, make token
an abstract
method in the base, provide an implementation in the derived class, and return the desired value. If you do this, you could replace the abstract class with an interface, because there would be no variables or implementations in it:
interface Operation { // Basic operation class
String getToken();
double operate (double x, double y);
}
class AddOp implements Operation {
public String getToken() {return "+"; }
public double operate (double x, double y) {
return x+y;
}
}
Alternatively, leave it unassigned in the base, add a constructor that takes the value of the token, and assign it there:
abstract class Operation { // Basic operation class
public final String token;
abstract public double operate (double x, double y);
protected Operation(String token) {this.token = token; }
}
class AddOp extends Operation {
public AddOp() { super("+"); }
public double operate (double x, double y) {
return x+y;
}
}
Upvotes: 3
Reputation: 424993
Static variables are referenced via the class. You have defined operator
as being of type Operation
, so operator.token
refers to Operation.token
.
I recommend using a getter for this purpose:
abstract Operation { \\ Basic operation class
abstract public double operate (double x, double y);
abstract public String getToken();
}
class AddOp extends Operation {
public double operate (double x, double y) {
return x+y;
}
public String getToken() {
return "+";
}
}
Upvotes: 3