Java多态性-根据子类型选择正确的方法
给定以下类和服务层签名:Java多态性-根据子类型选择正确的方法,java,design-patterns,polymorphism,Java,Design Patterns,Polymorphism,给定以下类和服务层签名: public class PersonActionRequest { PersonVO person // ... other fields } public class MyServiceLayerClass { public void requestAction(PersonActionRequest request) { PersonVO abstractPerson = request.getPerson();
public class PersonActionRequest {
PersonVO person
// ... other fields
}
public class MyServiceLayerClass {
public void requestAction(PersonActionRequest request)
{
PersonVO abstractPerson = request.getPerson();
// call appropriate executeAction method based on subclass of PersonVO
}
private void executeAction(PersonVO person) {}
private void executeAction(EmployeeVO employee) {}
private void executeAction(ManagerVO manager) {}
private void executeAction(UnicornWranglerVO unicornWrangler) {}
}
如前所述,java将在编译时根据类型信息选择最佳方法。(即,它将始终选择执行动作(PersonVO person))
选择正确方法最合适的方法是什么
告诉我使用instanceof
会让我挨耳光。但是,如果不明确地将abstractPerson
转换为其他具体类型之一,我看不到选择方法的合适方法
编辑:澄清-传入的VO是一个简单的ValueObject,用于web客户端实例化和传入。按照惯例,它没有方法,它只是一个带有字段的数据结构
因此,调用personVO.executeAction()
不是一个选项
谢谢
Marty如果
executeAction
是PersonVO
、EmployeeVO
、ManagerVO
和UnicornWranglerVO
通用的基类或接口中的一个方法,那么您可以调用abstractPerson.executeAction()
而不是有多个重写方法。我会显式地强制转换abstractPerson
。它不仅可以确保JVM获得正确的方法,还可以使其更易于阅读,并确保您知道发生了什么。您可以改变处理设计的方式,并使用,将执行器传递到Person
中,并让Person类型确定要调用的对象。访问者模式通常用于克服Java缺少双重分派的缺点。在这里,多态性的主要障碍似乎是“dumb struct”数据对象+“manager class”服务非模式。“更多态”的方法是将execute()作为各种person实现覆盖的方法
假设这一点无法改变,那么在Java中执行多个分派的方式是使用访问者查看回调
public interface PersonVisitor {
void executeAction(EmployeeVO employee);
void executeAction(ManagerVO manager);
void executeAction(UnicornWranglerVO unicornWrangler);
}
public abstract class PersonVO {
public abstract void accept(PersonVisitor visitor);
}
public class EmployeeVO extends PersonVO {
@Override
public void accept(PersonVisitor visitor) {
visitor.executeAction(this);
}
}
public class MyServiceLayerClass implements PersonVisitor {
public void requestAction(PersonActionRequest request)
{
PersonVO abstractPerson = request.getPerson();
abstractPerson.accept(this);
}
public void executeAction(EmployeeVO employee) {}
public void executeAction(ManagerVO manager) {}
public void executeAction(UnicornWranglerVO unicornWrangler) {}
}
如果有帮助的话,我不会因为你在那里使用instanceof而责骂你。你在使用继承吗?你的继承树在哪里?你有一个高度程序化的“Struct+Manager”体系结构。“我如何利用面向对象的优势,如多态性”这个问题的答案是切换到面向对象的设计域。调整你的VO这对你来说是正确的答案吗?也许不是。抛开狂热不谈,有时过程模式是解决问题的正确答案。instanceof有什么错?它是过程设计模式,不是OO模式,所以谁会在乎像多态性这样的OO原则?(还有“它很慢”)“现在很多JVM版本都不是这样。)不幸的是,VO只是一个只有字段的数据结构,没有行为。我已经更新了这个问题,让它更清楚。