I am stuck trying to figure out how I can use generics to check if the given object from a superclass, is the desired object from one of the subclasses of a subclass of this superclass. Let me give an example:
Let's say we have a this hierarchy:
public interface Expression{
public Object evaluate();
}
public abstract class BooleanExpression implements Expression{
public abstract Boolean evaluate();
}
public abstract class PositionExpression implements Expression{
public abstract Integer[] evaluate();
}
public class Conjunction extends BooleanExpression{
public Boolean evaluate()
}
public class BooleanTrue extends BooleanExpression{
@Override
public Boolean evaluate(){
return true;
}
}
Now my point is that the program should only be able to construct an object from Conjunction if and only if the given arguments in the constructor are either a BooleanExpression or a subclass of this class.
I have tried using generics like this:
public class Conjunction<T extends BooleanExpression> extends BooleanExpression{
public Conjuction(T left, T right){
this.left = left;
this.right = right;
}
private T left, right;
@Override
public Boolean evaluate(){
return (left.evaluate() && right.evaluate())
}
When I want to create an instance, I have the following code:
public Expression createConjunction(Expression left, Expression right){
return new Conjunction<BooleanExpression>(left, right)
}
But unfortunately this doesn't compile! I want to use generics to check whether left
and right
are instance of BooleanExpression
, because a Conjunction
can only be between two boolean values (and not a PositionExpression
).
However, left
and right
can be different BooleanExpression
, left
could be a Conjunction
while right
could be a BooleanTrue
(as example).
So a recap: I want to be able to create an instance of Conjunction
when both given arguments left
and right
are a subclass of BooleanExpression.
Creating an instance of Conjuction
with one of the argument being a subclass of PositionExpression
shouldn't be accepted by the compiler.
I want to solve this without changing the createConjunction
method and with using generic classes/interfaces. Any ideas?