簡體   English   中英

多態-構造相同類型的對象

[英]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();
    }
}

解決此問題的典型方法是為InheritedTypeInheritedType2引入一個公共超類。 顯然,這是因為這兩種類型共享邏輯,主要是:它們在左和右操作數上操作。 因此,讓我們創建一個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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM