gpt4 book ai didi

java - 不同类型的组合

转载 作者:行者123 更新时间:2023-11-29 06:53:44 24 4
gpt4 key购买 nike

我有两个 Java 类 B 和 C,它们都从类 A 扩展(我不拥有类 A)。

public class B extends A {…}
public class C extends A {…}

我需要一个“ListItem”类型的列表来保存 B 或 C 的实例,但由于(B 和 C)都已扩展,因此无法通过使用“ListItem”作为父类(super class)来进一步扩展它们。

我认为唯一的出路是组合(“has-a”关系……)。

因为“ListItem”永远不应该有 B 和 C(但只有其中一个),我计划用 2 个构造函数创建 ListItem 并设置一个适当的反射(reflect) B 或 C 是​​否被持有的内部类型。

是否有更好的方法来实现这一点?请看下面的伪代码。

public class ListItem {

private enum elemType {
TYPE_B, TYPE_C
}

private final B mBItem;
private final C mCItem;
private final elemType mType;

// used to hold instance of B
public ListItem(B b) {
this.mBItem = b;
this.mType = TYPE_B;
}

// used to hold instance of C
public ListItem(C c) {
this.mCItem = c;
this.mType = TYPE_C;
}

// sample method to demonstrate delegation
private int getAge() {
int age;

if (containsB()) {
age = mBItem.getAge();
}
else if (containsC()) {
age = mCItem.getAge();
}
else {…}
return age;
}

private boolean containsB() {
return (mType == TYPE_B);
}

private boolean containsC() {
return (mType == TYPE_C);
}
}

最佳答案

我的意思是,你有:

public class B extends A {…}
public class C extends A {…}

所以你可以让你的项目持有 A :

public class ListItem {

private final A item;

public ListItem (A item) {
this.item = item;
}

}

而且你有很多关于如何从那里处理它的选项,例如简单地:

    public A getItem () {
return item;
}

并从调用者那里做任何适当的转换或测试。这是最灵活的方式。或者我想是这样的:

    public B getB () {
return item instanceof B ? (B)item : null;
}

public C getC () {
return item instanceof C ? (C)item : null;
}

但这开始变得草率,并限制您存储任何其他 A衍生的东西在你的ListItem .

您可能想在这里开始质疑您的设计。例如,如果您要向 A 添加一些功能这对 B 很常见和 C 并且是 ListItem 正常运行所必需的,考虑从 A 派生一些类要添加常见的东西,派生 BC从那开始,让你的ListItem存储该基数(当然,如果您这样做,您将无法再存储 A):

public class AgedA extends A {
...
public int getAge () { return ... }
}

// Then your B and C both extend AgedA, and your ListItem stores an
// AgedA and can use getAge().

你可以制作AgedA抽象和getAge()是虚拟的,如果那更合适的话。或者您可以声明一个定义 getAge() 的接口(interface)并使用它。

另一种选择是您可以(如评论中指出的那样)制作 ListItem要么是一个接口(interface),要么是a class that extends A , 然后有你的 BC实现或扩展它。

我想你也可以 use generics对于 ListItem例如<? extends A> ,尽管这可能不合适,尤其是如果您的 ListItem s 是混合的。使用泛型的主要好处是,例如getters 现在可以直接返回子类型而无需强制转换,并且您可以在编译时将类型限制为函数参数和内容中的特定子类型,但除此之外它与仅存储 A 基本相同。 .

无论如何,除了存储 A 的建议之外在 ListItem并在更高级别处理不同的类型,凭良心我不能给你任何其他方法建议,因为对所有这些的需求对我来说似乎是有问题的。

关于java - 不同类型的组合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39215554/

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