簡體   English   中英

Java 中的子類特定覆蓋

[英]Subclass-specific override in Java

我的問題如下:

我們有一個可以在內部使用的算法

  • 具有“String getContent()”方法的表達式對象
  • 使用“表達式操作(表達式 e)”方法對表達式進行操作的操作器對象

這將成為 Java 中的框架。 要解決實際問題,需要給出表達式和操縱器的具體實現,算法 class 將執行 rest。

假設我們需要針對特定問題的 ProblemExpression 和 ProblemManipulator。

ProblemExpression 可能包含許多可供 ProblemManipulator 使用的新字段。

目前,我只能想到兩種編寫干凈代碼的方法:

  • 讓 ProblemManipulator.manipulate 假設它的 arguments 是 ProblemExpressions
  • 使用 instanceOf

但我覺得這不是我應該做的。 還有其他建議嗎?

預先問候並感謝您,

賽羅。

聽起來你應該使用泛型。 喜歡

interface Manipulator<E extends Expression> {
    public void manipulate(E expression);
}

class ProblemManipulator implements Manipulator<ProblemExpression> {
    public void manipulate(ProblemExpression expression) {
        // expression is a ProblemExpression
    }
}

由於“問題”是一個不同的問題,它可以是一個擴展 Expression 的接口,如下所示:

interface IProblemExpr extends Expression
{   //additional methods
}

class ProblemExpression implements IProbExpr
{
}

class ProblemManipulator()
{
    ProblemManipulator(IProblemExpr expr)
    {
     ..
    }
}

如果 ProblemExpressions 和 ProblemManipulators 都可以公開訪問,Generics 是不夠的。 起初我認為某種工廠框架可以解決問題。 即,表達式需要能夠創建操縱器,反之亦然。

例如,假設 ProblemManipulators 是 ProblemExpressions 的私有內部類 - 從 Expression#createManipulator(...) 獲得。

但是,這並不能完全解決問題......最后,如果允許算法“保留對”表達式和操縱器的引用,並且可以獲得不同的不相關實現,那么算法實現總是可以(如果不正確寫)最終為給定的表達式調用錯誤的操縱器 - 在編譯時無法做任何事情來防止這種運行時錯誤,因為所有操縱器都可以用任何表達式調用。

因此,在我看來,操縱器(或表達式)的調用必須“通過”表達式(或相反地操縱器),從而確保為給定的表達式調用正確的操縱器。

即,Expression 需要'manipulate()' 方法,該方法委托給適當的操縱器。

我研究了 generics 的工作方式,並提出了以下解決方案:

首先,我創建了兩個類,一個用於表達式,一個用於操縱器:

public class ObjectExpression { }

public class ObjectManipulator <E extends ObjectExpression> {

    public void calculate(Set<E> objects) {
        ... // Do something
    }
}

接下來,我創建了一個通用的算法 class。 需要兩個類:

  1. 一些表達

  2. 操縱這種類型的 object

我們得到:

public class Algorithm <F extends ObjectExpression, E extends ObjectManipulator<F>> {
    E om;

    public Algorithm( E om ) {
        this.om = om;
    }

    public void run(Set<F> objects) {
        om.calculate(objects);  
    }   
}

然后,我為 String 案例創建了一個實現:我們需要一個表達式和一個操縱器

public class StringExpression extends ObjectExpression {
}

public class StringManipulator extends ObjectManipulator<StringExpression> {

    @Override
    public void calculate(Set<StringExpression> objects) {
        // Do String stuff
    }
}

然后,我們可以為對象運行如下算法:

Algorithm<ObjectExpression, ObjectManipulator<ObjectExpression>> algo1 = new Algorithm<ObjectExpression, ObjectManipulator<ObjectExpression>>(manipo);
Set<ObjectExpression> objects = new HashSet<ObjectExpression>();
... // fill set
algo1.run(objects);

對於字符串:

StringManipulator manips = new StringManipulator();
Algorithm<StringExpression, StringManipulator> algo2 = new Algorithm<StringExpression, StringManipulator>(manips);
Set<StringExpression> strings = new HashSet<StringExpression>();
... // fill set
algo2.run(strings);

對我來說,這似乎是一個優雅的解決方案。 你怎么看? 任何替代/改進?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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