3

我有一些课程,里面X有这个领域A。它是一个最终字段,在构造函数中初始化。现在我有一个派生类Y,其中该字段必须始终是 的一个实例B,一个派生自 的类A。问题是,该类Y需要调用一些特定方法,这些方法仅在 B 类上可用,但在其祖先上不可用A

我看到了几个解决方案:

  1. 重用类型的字段A,继承自X,并在类内部Y强制A转换为B。这使我的代码充满了讨厌的类型转换。
  2. 添加另一个类型的字段B。现在没有类型转换,但我们有两个类型略有不同的字段,它们必须始终保持相同的值——也感觉不好。
  3. 将所有B提供的方法添加到Athrow NotImplementedException。这增加了一些奇怪的方法,这些方法在该类中故意没有意义。

处理这个领域的最正确方法是什么?或者也许还有其他更好的存在?我不认为这是非常特定于语言的,但在我使用的 Java 中必须是可行的。

4

3 回答 3

5

X 类型应该是泛型类型:

public class X<T extends A> {

    protected T a;

    public X(T a) {
        this.a = a;
    }
}

public clas Y extends X<B> {

    public Y(B b) {
        super(b);
    }

    public void foo() {
        // here, this.a is of type B, without any type cast.
    }
}
于 2013-01-26T20:21:25.910 回答
2

我能想到的唯一合理的解决方案是 #1 的变体:向类添加Y一个 getter 方法,该方法将字段转换为 type B,并仅通过此 getter 访问该字段。这只需要一次强制转换,并且作为一个有益的副作用,它还将记录代码的哪些部分要求该字段实际上是B.

于 2013-01-26T20:16:20.610 回答
2

在我看来,解决方案#1 是最正确的方法。如果您知道一个对象属于特定类,那么将其强制转换为该类没有任何问题。如果您在执行此操作时做出假设,那将是错误的,但这不是假设,根据您所说的。也许制作一个简单地将基础字段转换为正确类型并完成它的getter方法?这样,您只需转换一次(每个子类)。

如果字段以某种方式停止彼此正确更新,则解决方案 #2 将导致难以捉摸的运行时错误。这听起来像是最糟糕的解决方案。

解决方案#3 仍然感觉像是糟糕的软件设计。如果一个方法存在并且它不在抽象类中并且您没有处于原型设计阶段,那么应该实现该方法。否则,您可能只是通过给用户(类)一个误导性的界面来为用户(类)植入不必要的陷阱。

于 2013-01-26T20:21:12.697 回答