Java 派生类中的继承字段-这两种解决方案看起来都很蹩脚

Java 派生类中的继承字段-这两种解决方案看起来都很蹩脚,java,oop,inheritance,Java,Oop,Inheritance,我有一些类X,其中包含A字段。它是最后一个字段,在构造函数中初始化。现在我有一个派生类Y,其中该字段必须始终是B的实例,该类派生自a。问题是,类Y需要调用特定于数字的方法,这些方法仅在类B上可用,而在其祖先a上不可用 我看到了几种解决方案: 重用从X继承的A类型的字段,并在类Y内,将A强制转换为B。这使得我的代码充满了讨厌的类型转换 添加另一个B类型的字段。现在没有类型转换,但我们有两个类型稍有不同的字段,它们必须始终保持相同的值,而且感觉不太好 将B提供的所有方法添加到A,抛出NotImple

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

我看到了几种解决方案:

  • 重用从
    X
    继承的
    A
    类型的字段,并在类
    Y
    内,将
    A
    强制转换为
    B
    。这使得我的代码充满了讨厌的类型转换
  • 添加另一个
    B
    类型的字段。现在没有类型转换,但我们有两个类型稍有不同的字段,它们必须始终保持相同的值,而且感觉不太好
  • B
    提供的所有方法添加到
    A
    ,抛出
    NotImplementedException
    。这添加了一些奇怪的方法,这些方法在该类中故意没有意义

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

    我能想到的唯一合理的解决方案是#1的一个变体:添加到类
    Y
    一个getter方法,该方法将字段强制转换为类型
    B
    ,并仅通过该getter访问字段。这只需要一次转换,作为一个有益的副作用,它还将记录代码的哪些部分要求字段实际上是a
    B
    解决方案。在我看来,1是最正确的方法。如果您知道某个对象属于某个特定的类,那么将其强制转换到该类并没有什么错。如果你在做这件事的时候做假设是错误的,但根据你所说的,这不是一个假设。也许可以创建一个getter方法,简单地将底层字段强制转换为正确的类型,然后就可以使用它了?这样,您只需强制转换一次(每个子类)

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


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

    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.
        }
    }
    
    公共类X{
    保护性Tα;
    公共X(TA){
    这个a=a;
    }
    }
    公共类Y扩展X{
    公共图书馆Y(B){
    超级(b);
    }
    公共图书馆{
    //这里,这个.a是类型B,没有任何类型转换。
    }
    }
    
    Option#2在meAlso看来不错,Option#1可能是一个不错的解决方案。根据“full of”的含义,YMMV X不应该定义为
    X
    ,Y应该是
    Y扩展X
    ?你不会有任何类型的演员。同意。这似乎真的是一个想法。只有当
    A
    能够/应该预见
    B
    的存在时才适用。但是,这是一个很好的解决方案,Java在没有泛型的情况下应该可以做到。如果不能修改且不是泛型,则需要类型强制转换。