Der typische Weg, um dieses Problem ist es, eine gemeinsame übergeordnete Klasse für InheritedType
und InheritedType2
einzuführen. Dies liegt daran, dass diese beiden Typen offensichtlich eine gemeinsame Logik haben: Sie operieren sowohl auf linken als auch auf rechten Operanden. Also lassen Sie uns erstellen LeftRightType
(mangels eines besseren Namens):
abstract class LeftRightType extends Type {
private Type left, right;
public LeftRightType(Type left, Type right) {
this.left = left;
this.right = right;
}
@Override
public Type simplify() {
return newInstance(left.simplify(), right.simplify()).simplify();
}
public abstract Type newInstance(Type left, Type right);
}
Er hält die Logik, die Sie zur Zeit duplizieren und delegieren die Schaffung der konkreten Instanz in eine newInstance
abstrakte Methode, die Implementierer überschreiben. Dann können Sie einfach haben
class InheritedType extends LeftRightType {
public InheritedType(Type left, Type right) {
super(left, right);
}
@Override
public Type newInstance(Type left, Type right) {
return new InheritedType(left, right);
}
}
class InheritedType2 extends LeftRightType {
public InheritedType2(Type left, Type right) {
super(left, right);
}
@Override
public Type newInstance(Type left, Type right) {
return new InheritedType2(left, right);
}
}
Beachten Sie, dass wenn Sie mit Java 8 können Sie verdichten, dass eine Menge von der konkreten Klasse geben direkt im Konstruktor zurückzukehren. Sie brauchen nicht einmal mehr eine abstrakte Methode.
abstract class LeftRightType extends Type {
private Type left, right;
private BinaryOperator<Type> typeSupplier;
public LeftRightType(Type left, Type right, BinaryOperator<Type> typeSupplier) {
this.left = left;
this.right = right;
this.typeSupplier = typeSupplier;
}
public Type simplify() {
return typeSupplier.apply(left.simplify(), right.simplify()).simplify();
}
}
und dann haben
class InheritedType extends LeftRightType {
public InheritedType(Type left, Type right) {
super(left, right, InheritedType::new);
}
}
class InheritedType2 extends LeftRightType {
public InheritedType2(Type left, Type right) {
super(left, right, InheritedType2::new);
}
}
Ihr Code wirklich keinen Sinn macht. Jeder Aufruf von 'simplify' endet mit einem rekursiven Aufruf von' simplify'. Ihre Methoden beziehen sich auf Felder, die nicht deklariert sind. Daher ist nicht klar, wo sie deklariert werden sollen. Sie sollten ein minimales * korrekt * Beispiel posten, wenn Sie nützlichen Rat brauchen. – ruakh