Understanding inheritance of class variables - java

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?

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

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

Related

Java equivalent of instance initializer called after constructor

I've been reading about instance initializers in Java, and it's been explained that code common to all constructors can be put into them because they are called every time a new instance of a class is created. Is there an equivalent of instance initializers that run after constructors, for code that would be common to all constructors, but depends on what happens in the constructors?
No, there isn't an exact equivalent. If you want to run some common code, you can always factor out a method and call it at the end of all your constructors:
public class C {
private int x = 5;
private String y;
public C(int x) {
this.x = x;
endConstructor();
}
public C(String x) {
this.x = x.length;
endConstructor();
}
private void endConstructor() {
y = x + "!";
}
}
Sometimes, what seems like a situation where you want to call the same code at the "end" of all constructors can be refactored so that this code is in a single main constructor. Then, all other constructors call it using this(). For the example above:
public class C {
private int x = 5;
private String y;
public C(int x) {
this.x = x;
y = x + "!";
}
public C(String x) {
this(x.length);
}
}
The main constructor can be private, if appropriate.
Something like the #PostConstruct annotation can be used.
If your class has its dependencies injected using setter methods, then its constructor won't fully initialize an instance. Thus, additional "initializations" need to be performed after all the setter methods have been called.
If you think something happens in constructor:
class X {
private int x;
public X() {
// Code that sets x
// =-=-= HERE =-=-=
}
}
Insert the code you want to happen after the constructor... At the end of constructor.
If you have many constructors and don't want to duplicate code:
class X {
private int x;
public X() {
// Code that sets x
init();
}
public X(int x2) {
x = x2;
init();
}
private void init() {
// =-=-= HERE =-=-=
}
}
If every constructor invokes init, we may say this is invoked as a part of constructor, not after it. Imagine a train with one additional car following it, 50cm from it. Both have the same destination/time. Why couldn't we connect the train with standalone car?

How to update a variable declared in a different class? [duplicate]

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?
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;
}
}
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 "+";
}
}

Getting duplicate fields when setting from Concrete class

I need to define constant values in each ConcreteClass that extends AbstractClass. For some reason object ends up having duplicate fields, one set of fields is equal to zeros, next one has proper values.
SomeInterface
public interface SomeInterface{
double calculate();
}
AbstractClass
public abstract class AbstractClass implements SomeInterface{
double x, y;
public double calculate(){
return x*y;
}
}
ConcreteClass
public class ConcreteClass extends AbstractClass{
final double x = 1.1;
public setY(double y){
this.y = y;
}
}
I need my concrete class to store constant value final double x = 1.1; while inheriting the calculate() method implementation from abstract class.
You have declared x twice, so you get two x variables; one masks the other. It's doing what you told it to.
To have the concrete class set a value, put the setting of it in a (or all) constructor(s) of the ConcreteClass. Don't declare it again.
I don't know a way that you can declare it final and still alter it in a subclass.
You may be able to do something like this to get around - even though you cannot override instance variables in java.
If all you want to do is have Concrete class's have a constant variable, and the base abstract class use that for calculate method - You could try something like this..
public abstract class AbstractClass implements SomeInterface{
double x, y;
public void setX(double x){
this.x = x;
}
public double calculate(){
return x*y;
}
}
Then in the concrete class you could still have the final variable and have that passed in to the abstract class's setter.
public class TestAbstractVariable extends TestAbstract {
{
final double x = 1.1;
setX(x);
}
public void setY(double y){
this.y = y;
}
}
Hope it helps.
Thanks,
paul

Simulate function pointer

The following class contains a method that should calculate the integral using the callback technique.
package integrals;
import java.lang.*;
public class Integrals
{
public static double f1(double x)
{
return x*5+Math.sin(x);
}
public static double f2(double x)
{
return Math.pow(x*f1(-x),x);
}
public static double TrapezoidalIntegration(double a,double b,int n,double (*f)(double))
{
double rValue=0;
double dx;
dx=(b-a)/n;
for(double i=f(a);i<f(b);i+=dx)
rValue+=((f(i)+f(i+dx))*dx)/2.0;
return rValue;
}
public static void main(String[] args)
{
}
}
How to make a callback in this case? I prefer to avoid ☞such solution☜ due to it's complexity and ugliness. Even if it is the least painful, I don't have an idea how to implement it here.
How to make a callback in this case? I prefer to avoid such solution due to it's complexity and ugliness. Even if it is the least painful, I don't have an idea how to implement it here.
Since there are no function pointers in Java, you have to use a common interface instead. Your functions then have to be implementations of that interface. It is up to you whether you want to use names for those implementing classes (i.e. class F1 extends Function { … }) or anonymous classes instead (i.e. new Function { … }). It is also up to you whether you write the imp0lementation inside that class, or instead have the class implementation call one of your existing static functions.
Taking one example, with anonymous classes directly containing the implementation:
public class Integrals
{
public interface Function {
double eval(double x);
}
public static final Function f1 = new Function() {
public double eval(double x) {
return x*5+Math.sin(x);
}
};
public static final Function f2 = new Function() {
public double eval(double x) {
return Math.pow(x*f1.eval(-x),x);
}
};
public static double TrapezoidalIntegration(double a,double b,int n,Function f)
{
// … using f.eval(x) to compute values
This answer is valid for Java 7 or less that doesn't support closures nor callbacks.
First define an abstract class or an interface with a method that will calculate the integral value. For this sample, I'll define an interface:
interface IntegralCalculation {
double getIntegralValue(double x);
}
In your actual code, let's replace double (*f)(double) parameter for the interface and the method to use:
public static double TrapezoidalIntegration(double a,double b,int n, IntegralCalculation integralCalc) {
double rValue;
double dx;
dx=(b-a)/n;
// for(int i=f(a);i
Now, in your main method (or anywhere else where you will call this TrapezoidalIntegration method), pass an implementation of the interface. You can pass an instance of a class that implements the interface or an anonymous class.
Example using a class instance of a class that implements the interface (sorry, don't know other way to say it):
class BasicFunction implements IntegralCalculation {
#Override
public double getIntegralValue(double x) {
return x*5+Math.sin(x);
}
}
public class Integrals {
public static void main(String[] args) {
double x = TrapezoidalIntegration(0, 10, 10, new BasicFunction());
}
}
Using an anonymous class:
public class Integrals {
public static void main(String[] args) {
double x = TrapezoidalIntegration(0, 10, 10, new IntegralCalculation() {
private double f1(double x) {
return x*5+Math.sin(x);
}
#Override
public double getIntegralValue(double x) {
return Math.pow(x*f1(-x),x);
}
});
}
}
From the code above:
You can't pass a function pointer in Java, so double (*f)(double) parameter would be invalid, instead, we use an abstract class or an interface. IMO an interface would be better.
Once you have designed the interface, it must have a method that satisfy the rules of your function pointer. In this case, double (*f)(double) means a method that has a double as parameter and returns a double value. This is handled by getIntegralValue method.
After replacing the function pointer by the interface as parameter in TrapezoidalIntegration method, you should call the getIntegralValue as if it were the function pointer:
for(int i = integralCalc.getIntegralValue(a);
i < integralCalc.getIntegralValue(b); i += dx) { ... }

Is it common practice to have args in a method signature for the sole purpose of fulfilling a contract

I'm a little curious about some of the code that I saw at school and whether or not this is common practice in the field or just bad design.
Consider the following interface and the two classes that implement it...
public abstract interface Anchor
{
public abstract double x(double x);
public abstract double y(double y);
}
Notice in the Cycle class the arguments in x() and y() are actually used...
public class Cycle implements Anchor
{
public Anchor anchor;
public double radius;
public double period;
public double phase = 4.0D;
public Cycle(Anchor anchor, double radius, double period) {
this.anchor = anchor;
this.radius = radius;
this.period = period;
}
public double angle(double day) {
return this.phase * 3.141592653589793D * (day / this.period) / 2.0D;
}
public double x(double x) {
return this.anchor.x(x) + Math.cos(angle(x)) * this.radius;
}
public double y(double y) {
return this.anchor.y(y) + Math.sin(angle(x)) * this.radius;
}
}
But here in the Center class the arguments in x() and y() exist solely to fulfill the contact with the Anchor interface and aren't actually used in the method...
public class Center implements Anchor
{
public double x;
public double y;
public Center(double x, double y) {
this.x = x;
this.y = y;
}
public double x(double x) { return this.x; }
public double y(double y) { return this.y; }
}
Is this something that you'll see commonly in production java code? Is it an accepted practice or a bad work around?
Yes, this is very common to all OOP code.
An interface defines a set of methods that are available on any objects that implement that interface. The implementation of those methods is something that a caller isn't supposed to care about, and it's not at all unusual that some arguments seen in an interface don't apply to certain implementations.
While adpalumbo is correct that it's not an unusual situation, it can also be indicative of a design problem, particularly if you have a long list of parameters and each implementation uses a different one. E.g.
interface Waffle {
void iron(int a, int b, int c, int d, int e);
}
class Belgian implements Waffle {
void iron(int a, int b, int c, int d, int e) {
doSomethingWith(a);
}
}
class American implements Waffle {
void iron(int a, int b, int c, int d, int e) {
doSomethingElseWith(b);
}
}
class Scandinavian implements Waffle {
void iron(int a, int b, int c, int d, int e) {
andYetAgainWith(c);
}
}
// etc.
I like waffles, but that's just nasty.
The real question is whether the arguments, taken as a whole, make sense in the context of whatever the interface is supposed to represent.
To add in to 2 posts above, I would like to point out following.
The use of abstract keyword in interface declaration is considered very bad practice as this is considered obsolete, because the interface is considered abstract implicitly.
The use of abstract keyword in method declaration in the interface is considered extremely bad practice for the same reason as pointed in point 1 above. Methods declarations are implicitly abstract.
The use of Public keyword in method declaration is also considered very bad practice for the same reason, as methods declared in interface are implicitly public.
The methods in interface can not be static as static methods can't be abstract.

Categories