继承和转换:这是一个很好的java吗?

pit*_*las 5 java oop inheritance

看一下这段代码(从这里开始)

abstract class EntityA {
    AssocA myA;
    abstract void meet();
}

abstract class AssocA {
    int something;
    abstract void greet();
}

class AssocAConcrete extends AssocA {
    void greet() {
        System.out.println("hello");
    }
    void salute() {
        System.out.println("I am saluting.")
    }
}

class EntityAConcrete extends EntityA {
    void meet() {
        System.out.println("I am about to meet someone");
        ((AssocAConcrete)myA).salute();
    }
}
Run Code Online (Sandbox Code Playgroud)

对于父类和关联类,有两个并行的继承树.问题在于第23行:

((AssocAConcrete)myA).salute();

这是一种痛苦,我的代码中都有这种东西.尽管该行是Entity具体实现的一部分,但我需要提醒一下,我想使用AssocA,AssocAConcrete的具体实现.

是否有某种注释来声明这种关系?或者是否有更好的,更通俗的Java方式来表达这种设计?谢谢!


这是对@Dave的回应,因为我想把一些代码放进......

有趣!所以调用看起来像这样:

AssocAConcrete myAssoc = new Assoca();
EnitityA<T extends AssocA> myEntity = new EntityA<AssocAConcrete>();
myEntity.setAssoc(myAssoc);
myAssoc.salute();
Run Code Online (Sandbox Code Playgroud)

是?太棒了.我想我会用它!

Dav*_*ave 8

我认为使用泛型更加整洁......

abstract class EntityA<T extends AssocA> {

    // Basically, this means myA is at least an AssocA but possibly more...
    T myA;
    abstract void meet();
}

abstract class AssocA {
    int something;
    abstract void greet();
}

class AssocAConcrete extends AssocA {
    void greet() {
        System.out.println("hello");
    }
    void salute() {
        System.out.println("I am saluting.");
    }
}

class EntityAConcrete extends EntityA<AssocAConcrete> {
    void meet() {
        System.out.println("I am about to meet someone");
        myA.salute();
    }
}
Run Code Online (Sandbox Code Playgroud)

除了避免强制转换外,这也使得在AssocA实现中添加不同功能变得更加容易.应该总是有一种方法可以在不使用虚拟实现(即只抛出"NotImplementedException"的方法)或强制转换的情况下执行操作.即使重构时间并不总是那么容易或值得.换句话说,没有人会因为施法而责怪你(好吧......也许有些人会,但你不能讨好每个人).

编辑(实例化注释):

来自@pitosalas的评论如下......

//Won't work...can't call 'new' on abstract class AssocA
AssocAConcrete myAssoc = new Assoca();

//Instead, do this...
AssocAConcrete myAssoc = new AssocAConcrete();
Run Code Online (Sandbox Code Playgroud)

然后....

// Again, won't work.  T is only declaring the type inside your class/method.
// When using it to declare a variable, you have to say EXACTLY what you're making,
// or at least something as exact as the methods you're trying to invoke
EnitityA<T extends AssocA> myEntity = new EntityA<AssocAConcrete>();

//Instead do this...
EnitityA<AssocAConcrete> myEntity = new EntityAConcrete();

// Or this...
EntityAConcrete myEntity = new EntityAConcrete();
Run Code Online (Sandbox Code Playgroud)

然后这应该是好的......

// Assuming this is defined as `public void setAssoc(T newAssoc) {this.myA = newAssoc;}`
myEntity.setAssoc(myAssoc);
myAssoc.salute();
Run Code Online (Sandbox Code Playgroud)