2017-05-31 75 views
2

我有這種情況:執行方法/代碼基於運行時對象類型

我有一個抽象類,讓我們說A,實施多次。 在應用程序的另一部分,我有一個A對象的列表,並且我需要根據列表中對象的實際類型執行幾個操作。 作爲一個例子

/* package whatever; // don't place package name! */ 

import java.util.*; 
import java.lang.*; 
import java.io.*; 

abstract class A{ 
    abstract void op(); 
} 

class B extends A{ 
    void op(){ 
     System.out.println("b"); 
    } 
    void opB(){ 
     System.out.println("it's b again!"); 
    } 
} 

class C extends A{ 
    void op(){ 
     System.out.println("c"); 
    } 
    void opC(){ 
     System.out.println("it's b again!"); 
    } 
} 

class Ideone 
{ 
    public static void doStuff(B b){ 
     b.opB(); 
     //Some operation unique to class B 
    } 

    public static void doStuff(C c){ 
     //some operation unique to class C 
     c.opC(); 
    } 

    public static void main (String[] args) throws java.lang.Exception 
    { 
     List<A> l = someMethodThatGivesMeTheList(); 
     for(A a: l){ 
      //Here it should use the right 
      doStuff(a); 
     } 
    } 
} 

的例子並不編譯,但解釋了我想做的事情。怎麼樣?

我發現只有以應用Visitor模式的可能性,但這需要修改的A類和它的子類,接受訪問者,我寧願避免。

使用getClass()和開關\如果是笨拙的,而不是真的有什麼我要找的。

在這個例子中我用了兩個靜態方法,但一些新的類,包裝,什麼都可以,只要它解決了這個問題時,我有過代碼的完全控制。

這裏的一個類似的問題是Calling method based on run-time type insead of compile-time type,但在我的情況下,我正在使用Java,所以沒有dynamic類型存在來解決我的問題。

編輯:我寫在這裏我已經寫在評論什麼只是爲了使其更清晰。該操作不能成爲A的方法,因爲它代表必須分離的事物,如基於實際數據類型的GUI創建。一個並行層次結構可以作爲一個包裝器,但是仍然需要根據實際對象創建正確的GUI對象,這讓我想起了同樣的問題,至少在我看來這是這樣。

EDIT 2(返程):我已經改變了一點點的例子,以更好地表明,我需要根據實際的類做的東西。這是有點遠離我的情況,但問題是一樣的,一個集合擦除實物類,我需要一種方法來恢復它更聰明的是instanceofgetClass()

+0

將'C類獨特的某些操作'移動到'C#op'並使用動態分派。 –

+0

在我的情況下,這將違反視圖和模型之間的分離,因爲'//對C類特有的某些操作是在這種情況下創建GUI元素來操作數據,B和C是不同類型的數據共享相同的界面(A)。 – bracco23

回答

1

你檢查命令設計模式

interface A{ 
    void op(); 
} 

    class C implements A { 
    public void op() { 
     System.out.println("class c command method"); 
    } 
} 

class B implements A { 
    public void op() { 
     System.out.println("class B command method op"); 
    } 
} 

class D implements A { 
    public void op() { 
     System.out.println("class D method op"); 
    } 
} 

public class CommandDemo { 
    public static List produceRequests() { 
     List<A> list = new ArrayList<>(); 
     queue.add(new B()); 
     queue.add(new C()); 
     queue.add(new D()); 
     return list; 
    } 



    public static void main(String[] args) { 
     List list= produceRequests(); 
     for (Object command : list) { 
      ((A)command).execute(); 
     } 
    } 
} 

輸出

class B command method op 
class C command method 
class D method op 
+0

謝謝你的回答,不幸的是這不是我想要的。我想根據對象類型做不同的東西,但是不需要在這些類中寫任何東西。也許我沒有把它暴露出來,我會編輯這個問題。 – bracco23