java—如何将两个不相关的类连接到一个类型中而不使用inherenece

uyhoqukh  于 2021-07-11  发布在  Java
关注(0)|答案(2)|浏览(176)

我有两个班:x和y。它们都没有关联或具有相同的属性。但是还有另一个类z有setter和getter,其中setter可以接受x或y类型,getter可以返回x或y类型。我想为x,y创建一个父类parent,并将其用作setter和getter的类型。。但我不认为这是一个好的设计,会打破固有的全部意义。在这种情况下我能做什么?不是对z类使用泛型类型“t”

11dmarpk

11dmarpk1#

免责声明

正如其他人已经指出的,这是一个标志,在一开始的地方,糟糕的设计和气味。
考虑重新设计代码,这样就不需要同时返回两个不相关的东西。

代码

无论如何,这里有一些代码可以实现这种情况的解决方案。我们正在使用 Container 提供getter的类。但是只有一个有效,因此也有方法来检查哪一个有效。这样的类通常称为 Union 或者 Variant ,因为只允许包含其中一个类型。

public class Variant<X, Y> {
    public static <X, Y> Variant<X, Y> ofX(X x) {
        Objects.requireNonNull(x);
        return new Variant(x, null);
    }

    public static <X, Y> Variant<X, Y> ofY(Y y) {
        Objects.requireNonNull(y);
        return new Variant(null, y);
    }

    private final X x;
    private final Y y;

    private Variant(X x, Y y) {
        this.x = x;
        this.y = y;
    }

    public X getX() {
        if (x == null) {
            throw new IllegalStateException("Contains the other type");
        }
        return x;
    }

    public Y getY() {
        if (y == null) {
            throw new IllegalStateException("Contains the other type");
        }
        return y;
    }

    public boolean isX() {
        return x != null;
    }

    public boolean isY() {
        return y != null;
    }
}

用法:

Variant<String, Integer> variant1 = Variant.ofX("hello");
System.out.println(variant1.getX()); // hello

Variant<String, Integer> variant2 = Variant.ofY(20);
System.out.println(variant2.getY()); // 20

或者在你的具体例子中:

public Variant<String, Integer> foo() {
    ...
    if (...) {
        return Variant.ofX("hello");
    } else {
        return Variant.ofY(20);
    }
}

注意事项

使用静态工厂方法的目的是让两个不同的构造函数 X x 以及 Y y 只有在删除类型后才会产生相同的签名。所以这两个不同的方法名是必要的。
在一首颂歌“可选-所有自行车之母”,你可能还想考虑重命名 getX() 以及 getY() 听上去更严肃的事情,比如 getXOrThrow() / getYOrThrow() .

chhqkbe1

chhqkbe12#

如果一个方法有时返回不同的类型,那么很可能需要重写代码。您应该始终返回相同的类型。
通常,重新排列代码就足够了,但并不总是这样,这时实现某种包含嵌套对象的容器对象(纯粹为了返回它们)是很常见的。

相关问题