9

私はクラスを持っています:

class MyClass {

  public MyClass getParent() { ... }

  public MyClass[] getChildren() { ... }

  ....

}

そしてサブクラス

MySubClass extends MyClass {

  public String getId() { }

  ...
}

getChildren()またはgetParent()のインスタンスを使用MySubClassするたびに、これらのメソッドの結果をキャストする必要があります。

MySubClass sub = new MySubClass();
((MySubClass)sub.getParent()).getId();

そのキャストを回避する方法は (言語または設計によって) ありますか?

アイデアをありがとう!

更新 私が望むのは、呼び出されたインスタンスのタイプgetParent()getChildren()常に返すことです。たとえば、sub.getChildren()返す必要がありますMySubClass[]

4

7 に答える 7

14

自己型パターンを使用できます。

class MyClass<T extends MyClass<T>> { 
  public T getParent() { ... }
  public List<T> getChildren() { ... }  // you can use an array here too, but don't :)
}

class MySubclass extends MyClass<MySubclass> {
  public String getId() { ... }
}

getParentメソッドとメソッドを必要に応じて実装し、参照を保持getChildrenするフィールドを宣言し、それらが少なくとも参照として動作することを知ることができます。またはを呼び出すと、戻り値をどこにもキャストせずにインスタンスとして使用できます。MyClassTMyClassgetParentgetChildrenMySubClassMySubClass

このアプローチの主な欠点は、これまでに見たことがない人がかなり混乱する傾向があることです。

于 2013-09-30T11:17:33.567 に答える
4

そのキャストを回避する方法は (言語または設計によって) ありますか?

答えはノーです。スーパークラスのフィールドまたはメソッドにアクセスしたい場合は、明示的にキャストする必要があります。

于 2013-09-30T11:04:36.743 に答える
4

Java 5.0 から、共変の戻り値の型でメソッドをオーバーライドできます。つまり、メソッドをオーバーライドして、サブクラスの親クラスを返すことができます。( Java での共変の戻り値の型を参照してください):

public class MySubClass extends MyClass {

  @Override
  public MySubClass getParent() {
    return (MySubClass) super.getParent();
  }

  @Override
  public MySubClass[] getChildren() {
    return (MySubClass[]) super.getChildren();
  }

  public String getId() {
    ...
  }
}

その後、 を呼び出すことができますnew MySubClass().getChildren()[0].getId()

もちろん、これはMySubClass常に MySubClass インスタンスを親および/または子として持つ場合にのみ機能します

于 2013-09-30T11:13:23.683 に答える
1

おそらくジェネリックを使用する(http://docs.oracle.com/javase/tutorial/extra/generics/index.html

次のようなものが必要です。

public class MyClass<T extends MyClass> {

    public T getParent() { return null; }

    public MyClass[] getChildren() {
        return null;
    }

    public static void main(String[] args) {
        MyClass<MySubClass> o = new MySubClass();
        o.getParent().getId();
    }
}

class MySubClass extends MyClass<MySubClass> {

    public String getId() {
        return "";
    }
}
于 2013-09-30T11:13:42.527 に答える
1

MySubClassはい、 a の親と子は常に型になることがわかっていると仮定しますMySubClass

その場合、戻り値の型を絞り込み、MySubClassそこでキャストを行うことができます。

MySubClass extends MyClass() {
    @Overrides
    public MySubClass getParent() { return (MySubclass) super.getParent(); }

    @Overrides
    public MySubClass[] getChildren() { return (MySubclass[]) super.getChildren(); }

    public String getId() { }

    ...
}
于 2013-09-30T11:12:03.067 に答える
0

実際に何をしようとしているかに応じて、基本クラスを抽象化し、getId() を追加します。

abstract class MyClass() {
    public MyClass getParent() { ... }
    public MyClass[] getChildren() { ... }
    public String getId();
    ....
}

MySubClass extends MyClass() {
    @Overrides
    public String getId() { }
    ...
}

または、要件に応じて、基本クラスに getId() を実装します。

class MyClass() {
    public MyClass getParent() { ... }
    public MyClass[] getChildren() { ... }
    public String getId() { }
    ....
}

MySubClass extends MyClass() {
    ...
}
于 2013-09-30T11:06:49.847 に答える