我有一個這樣的類結構:
LineTemplate (abstract)
/ \
LineOut (abstract) LineIn (final)
/ \
LineOutTransfers (final) LineOutSells (final)
這兩個線路輸出和LINEIN應該從檔案中讀取一行,檢查其內容對資料庫和運行多個查詢。
然而,LineOut包含兩個略有不同的變體,這取決于行的內容。由于LineOutTransfers和LineOutSells在呼叫它們的方法時執行不同的操作,我決定繼承并將它們視為子類。
我創建了一個公共靜態LineTemplate __init()內的方法LineTemplate以確定它是否是一個線路輸出或LINEIN類,并回傳基于外部條件的正確的型別,我想實作一個類似的方法來確定正確的型別的線路輸出子類。
但是,由于LineOut子項取決于行內容,因此我被困在了這一點上。該類應該讀取該行,然后將自身轉換為正確的子級,然后執行檢查。但這是不可能的,因為我不能將父類轉換為子類,如果它不是那種型別(多型)。
我還想過讀取LineOut的__init()方法中的所有行,然后將變數作為引數傳遞給它的子建構式,但是由于有一堆變數要讀取,并且由于它在LineIn 中的處理方式不同,因此在我看來,這是一種不好的做法。
有任何想法嗎?提前致謝。
uj5u.com熱心網友回復:
你能添加一個convertWithContext(SomeClassRepresentingContext ctx)方法來LineOut回傳一個新的LineOut,它將是 LineOut 的正確子類嗎?
另一種方法是使用工廠方法并為其提供行內容和背景關系。就像是
LineOutFactory.instance().constructLineOut(String line, SomeClassRepresentingContext ctx);
在 Java 中,一旦創建類,就不能更改類的型別,只能根據現有類的內容和可能的外部背景關系構建新類。
uj5u.com熱心網友回復:
喜歡組合而不是繼承,所以而不是
abstract class LineOut {
public void consume(Line l) {
// ...
subclassConsume(l);
// ...
}
protected abstract void subclassConsume(Line l);
}
// and
class LineOutTransfers extends LineOut {
protected abstract void subclassConsume(Line l) { ... }
}
class LineOutSells extends LineOut {
protected abstract void subclassConsume(Line l) { ... }
}
你應該做這個
abstract class LineOut {
private TransferLineHandler transferHandler;
private SellsLineHandler sellsHandler;
public void consume(Line l) {
// ...
if (isTransfer(l)) {
transferHandler.consume(l);
} else {
sellsHandler.consume(l);
}
// ...
}
protected abstract void subclassConsume(Line l);
}
// with
class TransferLineHandler {
public consume(l) { // stuff from LineOutTransfers }
}
class SellsLineHandler {
public consume(l) { // stuff from LineOutSells }
}
這完全消除了“動態子類化”問題,并使代碼更易于測驗。
uj5u.com熱心網友回復:
也許工廠方法對這種情況有用:https : //refactoring.guru/design-patterns/factory-method
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/381350.html
上一篇:MVC5中的繼承
下一篇:C#呼叫兩個介面相同的類
