2009-06-15 33 views
0

在Java中,我有一個名爲Operation的抽象類和三個名爲OperationActivation,OperationPayment和OperationSendEmail的子類。Java多態方法

添加來自評論:操作*對象是EJB實體Bean,所以我不能在它們內部有業務邏輯。

不,我想創建處理器類這樣的:

public class ProcessOperationService { 

public void processOperation(Operation operation) { 
    out.println("process Operation"); 
    process(operation); 
} 

public void process(OperationActivation operationActivation) { 
    out.println("process Activation"); 
} 

public void process(OperationPayment operationPayment) { 
    out.println("process Payment"); 
} 

public void process(OperationSendEmail operationSendEmail) { 
    out.println("process OperationSendEmail"); 
}   

}

處理每個操作需要不同的邏輯,所以我想有三種不同的方法,一個用於每個操作。

當然這個代碼不會編譯。我錯過了什麼,或者它不能這樣做?

回答

4

您的Operation*物體不應該自己做這項工作嗎?所以,你可以寫(說)

for (Operation op : ops) { 
    op.process(); 
} 

您可以封裝邏輯在自己的類中的每個特定的操作,並且這種方式有關的一切OperationPayment保持在OperationPayment類。您不需要處理器類(因此,您不需要每次添加操作時都修改處理器類)

有更復雜的模式可以使對象調解wrt。他們需要執行什麼,但我不確定在這個階段你需要複雜的東西。

+0

操作*對象是EJB實體Bean,所以我不能在他們裏面的業務邏輯。 – mgamer 2009-06-15 11:13:48

+0

然後我會考慮用包含相關邏輯的對象包裝它們。這很簡單,因爲你將對象和它們的功能綁在一起,並且當你添加新的實體時,你不需要維護單獨的對象 – 2009-06-15 11:19:30

1

假設:操作

除非processOperation(操作)方法的操作*對象是子類在執行一些常用的功能,你可以只是將其刪除,並揭露過程(操作)的方法。

命令模式(JavaWorld Explanation)可能很有用,但要確切地告訴你想從你的問題中得到什麼屬性是很棘手的。

5

您正在混合重載和多態方法處理。當您根據參數類型重載方法時,即靜態多態性。這些方法應該從編譯時知道類型是什麼的代碼中調用。你可能做到以下幾點,但它不會是乾淨的面向對象的代碼:

public class ProcessOperationService { 

public void processOperation(Operation operation) { 
    out.println("process Operation"); 
    if (operation instanceof OperationActivation) 
     process((OperationActivation)operation); 
    else if (operation instanceof OperationPayment) 
     process((OperationPayment)operation); 
    ... 
} 

public void process(OperationActivation operationActivation) { 
    out.println("process Activation"); 
} 
... 
} 

這將是更好的讓自動運行時多態性的工作,通過做布賴恩·阿格紐建議,並使進程是每個操作子類型本身的一種方法。

1

代碼的問題是任何匹配進程(Operation *)方法之一的對象也將匹配進程(Operation)方法。由於可以使用兩種方法,因此編譯器會警告您模糊的情況。

如果你真的想/需要上面的代碼,我會建議實施過程中(操作*)方法,並修改過程(操作)方法,因此被稱爲processCommon(操作)。然後,每個進程(Operation *)所做的第一件事就是調用processCommon。

或者,您可以使用instanceof比較完全按照Avi的說法進行編碼。

兩者都不是理想的,但它會完成你想要的。

1

因此,您有一個名爲'操作'的抽象類,它有3個類擴展它。不知道這是否是你所追求的,但我會想象它的設計是這樣的:

Operation.java

public abstract class Operation { 

    public abstract void process(); 

} 

OperationActivation.java

public class OperationActivation extends Operation { 

    public void process() { 

     //Implement OperationActivation specific logic here 

    } 

} 

OperationPayment.java

public class OperationPayment extends Operation { 

    public void process() { 

     //Implement OperationPayment specific logic here 

    } 

} 

OperationSendEmail.java

public class OperationSendEmail extends Operation { 

    public void process() { 

     //Implement OperationSendEmail spepcific logic here 

    } 

} 

ProcessOperationService.java

public class ProcessOperationService { 

    public void processOperation(Operation operation) { 

     out.println("process Operation"); 
     operation.process(); 

    } 

} 
1

不會Visitor模式是用在這裏?

類操作可以聲明,需要一個訪問者對象「接受」方法和子類可以具有提供的實現:

public interface IOperationVisitor { 
    public void visit (OperationActivation visited); 
    public void visit (OperationPayment visited); 
    public void visit (OperationSendEmail visited); 
} 

abstract class Operation {  
    public void accept(IOperationVisitor visitor)(); 
} 

class OperationActivation extends Operation { 
    public void accept(IOperationvisitor visitor) { 
     visitor.visit(this); 
    } 
} 

類似地定義「接受」方法的類OperationPayment和OperationSendEmail ..

現在

類可以實現訪問者:

public class ProcessOperationService implements IOperationVisitor { 

    public void processOperation(Operation operation) { 
     operation.accept(this); 
    } 

    public void visit (OperationActivation visited) { 
     // Operation Activation specific implementation 
    } 

    public void visit (OperationPayment visited) { 
     // OperationPayment specific implementation 
    } 

     public void visit ((OperationSendEmail visited) { 
     // (Operation SendEmail specific implementation 
     } 
    }