派生类中的继承字段 - 两种解决方案都显得蹩脚

时间:2013-01-26 20:11:14

标签: java oop inheritance

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

我看到了几个解决方案:

  1. 重复使用A类型的字段,继承自X,并在类Y内,将A投射到B。这使我的代码充满讨厌的类型转换。
  2. 添加B类型的其他字段。现在没有类型转换,但我们有两个略有不同类型的字段,必须始终保持相同的值 - 也感觉不太好。
  3. B提供的所有方法也添加到A,抛出NotImplementedException。这增加了一些奇怪的方法,这些方法在那个课程中明显没有意义。
  4. 哪种方式最适合处理这个领域?或者其他一些,更好的存在?我认为这不是特定于语言的,但我必须在Java中使用。

3 个答案:

答案 0 :(得分: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.
    }
}

答案 1 :(得分:2)

我能想到的唯一理智的解决方案是#1的变体:向类Y添加一个getter方法,该方法返回转换为类型B的字段,并仅通过此方法访问该字段吸气。这只需要一次演员表,作为一个有益的副作用,它还会记录代码的哪些部分要求该字段实际上是B

答案 2 :(得分:2)

在我看来,解决方案#1是最正确的方式。如果你知道某个对象是一个特定的类,那么将它强制转换为该类是没有错的。如果你在做这个时做出假设是错误的,但根据你所说的,这不是一个假设。也许制作一个getter方法,简单地将底层字段转换为正确的类型并完成它?这样,你只需要施放一次(每个子类)。

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

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