[英]Polymorphism - construct an object of the same type
让我们考虑这个例子:
class InheritedType extends Type {
public Type simplify() {
Type newLeft = left.simplify();
Type newRight = right.simplify();
Type newExpr = new InheritedType(newLeft, newRight);
return newExpr.simplify();
}
}
现在,我将创建另一个继承的类型
class InheritedType2 extends Type {
public Type simplify() {
Type newLeft = left.simplify();
Type newRight = right.simplify();
Type newExpr = new InheritedType2(newLeft, newRight);
return newExpr.simplify();
}
}
此方法是相同的,只是构造函数名称不同。 有什么办法可以避免代码重复? 以下代码不起作用
class Type {
public Type simplify() {
Type newLeft = left.simplify();
Type newRight = right.simplify();
Type newExpr = new this(newLeft, newRight);
return newExpr.simplify();
}
}
解决此问题的典型方法是为InheritedType
和InheritedType2
引入一个公共超类。 显然,这是因为这两种类型共享逻辑,主要是:它们在左和右操作数上操作。 因此,让我们创建一个LeftRightType
(由于缺少更好的名称):
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);
}
它包含您当前正在复制的逻辑,并将具体实例的创建委派给实现者将覆盖的newInstance
抽象方法。 然后,您可以简单地拥有
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);
}
}
请注意,如果您使用的是Java 8,则可以通过提供具体类以直接在构造函数中返回的方式来简化很多内容。 您甚至不再需要抽象方法。
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();
}
}
然后有
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);
}
}
您可以“好奇地重复使用模板模式” https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern :
abstract class Type<This extends Type<This>> {
protected abstract This newInstance(Type<?> newLeft, Type<?> newRight);
public This simplify() {
Type<?> newLeft = left.simplify();
Type<?> newRight = right.simplify();
This newExpr = newInstance(newLeft, newRight);
return newExpr.simplify();
}
}
class InheritedType extends Type<InheritedType> {
protected InheritedType newInstance(Type<?> left, Type<?> right) {
new InheritedType(left, right);
}
}
class InheritedType2 extends Type<InheritedType2> {
protected InheritedType2 newInstance(Type<?> left, Type<?> right) {
new InheritedType2(left, right);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.