Java多态方法

时间:2009-06-15 10:59:56

标签: java polymorphism

在Java中,我有一个名为Operation的抽象类,以及三个名为OperationActivation,OperationPayment和OperationSendEmail的子类。

ADDED FROM COMMENT:Operation *对象是EJB Entity Beans,所以我不能在其中包含业务逻辑。

不,我想创建这样的处理器类:

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");
}        

}

处理每个操作需要不同的逻辑,所以我想有三种不同的方法,每种方法一个。

当然这段代码不能编译。我错过了什么或不能这样做吗?

6 个答案:

答案 0 :(得分:5)

您正在混合重载和多态方法处理。当您根据参数类型重载方法时,即 static 多态。应该从编译时知道类型是什么的代码调用这些方法。您可以执行以下操作,但它不是干净的面向对象的代码:

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");
}
...
}

通过像Brian Agnew建议的那样让自动运行时多态性工作更好,并使进程成为每个Operation子类本身的一种方法。

答案 1 :(得分:4)

你的Operation*对象不应该自己做这项工作吗?所以你可以写(说)

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

您可以将每个特定操作的逻辑封装在自己的类中,这样与OperationPayment相关的所有内容都保留在OperationPayment类中。您不需要Processor类(因此每次添加操作时都不需要修改Processor类)

有更复杂的模式可以让对象调解wrt。他们需要执行什么,但我不确定你在这个阶段需要一些复杂的东西。

答案 2 :(得分:1)

假设:Operation *对象是Operation

的子类

除非processOperation(Operation)方法执行某些常用功能,否则您可以将其删除并公开进程(Operation)方法。

命令模式(JavaWorld Explanation)可能很有用,但要准确说出你想从问题中找到哪些属性是很棘手的。

答案 3 :(得分:1)

代码的问题是任何与进程(Operation *)方法之一匹配的对象也将与进程(Operation)方法匹配。由于有两种方法可以使用,编译器会警告您存在模糊情况。

如果 确实 想要/需要上面的代码,我建议实现进程(Operation *)方法,并修改进程(Operation)方法,以便它是调用processCommon(Operation)。然后,每个进程(Operation *)所做的第一件事就是调用processCommon。

或者,您可以使用instanceof比较完全按照Avi所说的编码。

两者都不理想,但它会实现你想要的。

答案 4 :(得分:1)

所以你有一个名为' Operation '的抽象类,它有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();

    }

}

答案 5 :(得分:1)

访客模式不会在这里使用吗?

类Operation可以声明一个“accept”方法,该方法接受一个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 ..

定义“accept”方法

现在,您的班级可以实施访问者:

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
       }
  }