2009-06-15 72 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 
     } 
    }