gpt4 book ai didi

java - 处理父类(super class)型的所有子类型

转载 作者:行者123 更新时间:2023-12-01 17:32:16 26 4
gpt4 key购买 nike

处理抽象父类(super class)型的不同子类型作为参数的最佳方法是什么,例如在处理事件时。

情况如下:

父类(super class)型:

public interface MySuperInterface {
}

子类型

public class SubclassA implements MySuperInterface {
}

另一种亚型

public class SubclassB implements MySuperInterface {
}

一些应该能够处理 MySuperInterface 的任何子类型的类

public class MySuperHandler {

public void handle(MySuperInterface mysuper) {
//do it
}

}

我的不同方法是

  1. 处理程序方法中的 switch/case 语句。 (我不喜欢)

  2. 接口(interface)中的方法receive(MySuperHandler)以及对该方法的调度在handle方法内部:mysuper.receive(this)(这意味着接口(interface)知道处理程序类)

  3. 为 MySuperHandler 类中的每个子类型添加句柄方法(这并不能确保每个子类型都可以被处理)

但由于上述原因,我对这些解决方案并不满意。

有什么办法可以处理这种情况吗?

谢谢

最佳答案

一种方法是使用 Visitor Pattern 。它看起来像这样:

public interface MySuperInterface {
<T> T acceptVisitor(MySuperInterfaceVisitor<T>);
}

public interface MySuperInterfaceVisitor<T> {
T visitA(SubclassA a);
T visitB(SubclassB a);
}

public class SubclassA implements MySuperInterface {
<T> T acceptVisitor(MySuperInterfaceVisitor<T> visitor) {
return visitor.visitA(this);
}
}

public class SubclassB implements MySuperInterface {
<T> T acceptVisitor(MySuperInterfaceVisitor<T> visitor) {
return visitor.visitB(this);
}
}

public class MySuperHandler implements MySuperInterfaceVisitor<Foo>{
Foo visitA(SubclassA a) {
// construct Foo from SubclassA instance
}

Foo visitB(SubclassB a) {
// construct Foo from SubclassB instance
}
}

这有点像你的#2,除了接口(interface)(和子类)不需要知道处理程序。他们只需要了解访客界面即可。如果您不想让 MySuperInterface 及其实现了解您的特定处理程序,那么这很好。

顺便说一句,而不是调用:

myHandler.handle(myImpl);

你会打电话:

myImpl.acceptVisior(myHandler);

如果您想确保每个处理程序都可以处理接口(interface)的每个实现,但仍然阻止实现了解所有存在的“处理程序”,那么这种方法很好。

如果您添加接口(interface)的另一个实现 (MySuperInterface),编译器将强制您添加 acceptVisitor 方法。此方法可以使用现有的 visit* 方法之一,或者您必须向访问者界面添加一个新方法。如果您执行后者,则必须更新所有访问者(也称为“处理程序”)实现。这确保了以后可以处理每个子类型。

这种方法比 assylias 的答案中的方法更复杂,并且只有当您想要打破 MySuperInterface 的实现和处理程序代码之间的耦合,或者您有一个强大的希望组织您的处理程序代码,以便特定类型处理的所有代码“在一起”。

访问者模式的一种常见用途是以不同的方式呈现对象。假设您希望能够将对象转换为 PDF 或 HTML。您的界面中可以有一个 toHTML 和一个 toPDF 方法。这种方法的缺点是,现在您的类依赖于您的库来生成 HTML 和 PDF。另外,如果后来有人想要添加新的输出类型,他们需要修改这些核心类,这可能是不可取的。使用访问者模式,只有访问者类需要了解 PDF 或 HTMl 库,并且可以在不修改核心类的情况下添加新访问者。 (但是,添加新的核心类意味着您要么需要让它们重用现有的 visit* 方法,要么您必须修改所有访问者实现。)

关于java - 处理父类(super class)型的所有子类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9819206/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com