Ich stecke fest, herauszufinden, wie ich Generics verwenden kann, um zu überprüfen, ob das gegebene Objekt aus einer Oberklasse das gewünschte Objekt aus einer der Unterklassen einer Unterklasse dieser Oberklasse ist . Lassen Sie mich ein Beispiel geben:Generics und type safety: Überprüfen der dynamischen Bindung von Argumenten
Lassen Sie uns sagen, dass wir diese Hierarchie haben:
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;
}
}
Nun ist mein Punkt ist, dass das Programm nur in der Lage sein sollte, ein Objekt aus Conjunction, wenn und nur wenn die gegebenen Argumente zu konstruieren, in Der Konstruktor ist entweder eine BooleanExpression oder eine Unterklasse dieser Klasse.
Ich habe mit Generika wie dies versucht:
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())
}
Wenn ich eine Instanz erstellt werden soll, ich habe den folgenden Code:
public Expression createConjunction(Expression left, Expression right){
return new Conjunction<BooleanExpression>(left, right)
}
Aber leider nicht kompilieren! Ich möchte Generics verwenden, um zu überprüfen, ob left
und right
Instanzen von BooleanExpression
sind, weil ein Conjunction
nur zwischen zwei booleschen Werten sein kann (und nicht ein PositionExpression
). left
und right
können jedoch unterschiedlich sein BooleanExpression
, left
könnte ein Conjunction
sein, während right
könnte ein BooleanTrue
(als Beispiel) sein.
Also eine Zusammenfassung: Ich möchte in der Lage sein, eine Instanz von Conjunction
zu erstellen, wenn beide gegebenen Argumente left
und right
eine Unterklasse von BooleanExpression sind. Das Erstellen einer Instanz von Conjuction
mit einem Argument, das eine Unterklasse von PositionExpression
ist, sollte vom Compiler nicht akzeptiert werden.
Ich möchte dies lösen, ohne die createConjunction
Methode und mit generischen Klassen/Schnittstellen zu ändern. Irgendwelche Ideen?
Sie müssen die Funktion 'createConjunction' definitiv ändern, da sie in ihrer aktuellen Form einfach ungültig ist. Alles, was Sie ändern sollten, ist, die Typen von "links" und "rechts" "Boolescher Ausdruck" anstelle von "Ausdruck" zu machen. – luk2302
Der Compiler macht genau das, was er soll.Es kompiliert nicht, weil "links" und "rechts" Ausdrücke sind, aber Ihr "Conjection" -Konstruktor erfordert explizit, dass diese Unterklassen von 'BoolescherAusdruck' sind. – Casey
@Casey Ich denke, es gibt keine Möglichkeit für den Compiler zu überprüfen, ob das zugrunde liegende Objekt von 'left' von der Unterklasse' BooleanExpression' ist, oder? (zB wenn ich diese Methode 'createConjunction' nenne, könnte das' left' Argument ein 'BooleanTrue' enthalten, welches eine Unterklasse von' BooleanExpression' ist) ( –