[英]avoiding instanceof
我有一組具有共同超類的POJO。 它們存儲在類型超類的二維數組中。 現在,我想從數組中獲取一個對象並使用子類的方法。 這意味着我必須將它們轉換為子類 。 有沒有辦法在不使用instanceof的情況下執行此操作?
更新:作為一個具體的例子: http : //obviam.net/index.php/the-mvc-pattern-tutorial-building-games/請參閱: “點擊敵人時添加新動作(攻擊)”
是的 - 您可以通過反轉流來完成:當基類的實例是特定類型時,代替您的代碼執行操作,將操作項傳遞給對象,並讓對象決定是否執行它。 這是訪客模式背后的基本技巧。
interface DoSomething {
void act();
}
abstract class AbstractBaseClass {
abstract void performAction(DoSomething ds);
}
class FirstSubclass extends AbstractBaseClass {
public void performAction(DoSomething ds) {
ds.act();
}
}
class SecondSubclass extends AbstractBaseClass {
public void performAction(DoSomething ds) {
// Do nothing
}
}
AbstractBaseClass array[] = new AbstractBaseClass[] {
new FirstSubclass()
, new FirstSubclass()
, new SecondSubclass()
, new FirstSubclass()
, new SecondSubclass()
};
for (AbstractBaseClass b : array) {
b.performAction(new DoSomething() {
public void act() {
System.out.println("Hello, I'm here!");
}
});
}
如果您知道它們屬於子類類型,那么只需直接轉換它們而不進行instanceof
檢查。
但是將它們放在一個超類型數組中告訴編譯器丟棄它們實際上屬於子類類型的信息。 您的超類應該公開那些方法(可能是抽象的),或者您的數組應該是子類類型(因此您不會告訴編譯器忘記對象的實際類型),或者您必須將其吸收並執行轉換(可能使用instanceof
測試)。
唯一另一個值得注意的替代方案是您可以嘗試訪問者模式,該模式將操作傳遞給對象並讓對象決定如何處理它。 這允許您覆蓋要忽略的類或根據其運行時類型執行操作。
您可以嘗試使用訪問者設計模式。 http://en.wikipedia.org/wiki/Visitor_pattern
你必須問自己,為什么你需要知道它們的類型,也許這可以用超類中的抽象方法替換,每個人都可以根據所需的結果實現。
abstract class A{
abstract void visit();
}
class B extends A{
void visit() { print("B"); }
}
class C extends A {
void visit() { print("C"); }
}
我會避免在第一時間施放它們。
真的想想你要做什么,以及它們是否應該在同一個系列中。
如果你有類似的東西
for(MyObj o : array) {
if(o instanceof A) {
((A)o).doA();
}
if(o instanceof B) {
((B)o).doB();
}
}
考慮一下這個
abstract class MyObj {
abstract void doIt();
}
class A {
void doIt() { doA(); }
}
class B {
void doIt() { doB(); }
}
在超類中公開該方法,然后使用重寫。 在基類中提供一個空實現,以便子類可以在需要時忽略該操作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.