1

以下に示すように、多くの子を持つドメインクラスがあります ( B はインターフェースタイプで、 B1 と B2 ) B インターフェースを実装しています。

私のメインクラスでわかるように、 (B1 b1 = (B1) a.getB();) をキャストする必要があり、それが B1 または B2 であることがわかっているので、私の知識では問題ありません。

私が抱えている問題は、型が大きくなる可能性があることです.Aを使用する人は、Bのインスタンスをチェックし、B1またはB2の特定の値にアクセスするために、より多くの条件を設定する必要があります...このキャストをスキップして、将来的に多くの条件を減らす

public class TestMain
{
  public static void main(String[] args)
  {
    A a = new A();
    //this can be B1 or B2 
    B1 b1 = (B1) a.getB();
  }
}

public class A
{
  private B b;

  protected B getB()
  {
    return b;
  }

  protected void setB(B b)
  {
    this.b = b;
  }
}

public interface B
{
  void test();
}

public class B1 implements B
{
  @Override
  public void test()
  {
    // TODO Auto-generated method stub
  }
}
public class B2 implements B
{
  @Override
  public void test()
  {
    // TODO Auto-generated method stub
  }
}
4

4 に答える 4

2

この機能が本当に必要であると仮定すると (上記の Eran のコメントは良い点を示しています。ポリモーフィズムは、必要なことのほとんどまたはすべてを実行する可能性があります)、答えはジェネリックです。これらは少し高度なトピックですが、Java の中心となるため (JDK のすべてのコレクション クラスで使用されます)、習得することが非常に重要です。

ジェネリックとは、「ある型」、およびオプションで「他の型のサブタイプである型」を表す方法です。後者はあなたが望むものです。

public class A<T extends B>
{
  private T b;

  protected T getB()
  {
    return b;
  }

  protected void setB(T b)
  {
    this.b = b;
  }
}

<T extends B>パーツは のジェネリック パラメータを宣言し、のTサブクラスでなければならないと述べていBます。それ以降は、クラスT内の型であるかのように使用できます。Aこのクラスのユーザーは、クラスの種類を指定する必要がAあり、コンパイラが自動的にダウンキャストを行います。

A<B1> a = new A<B1>();
a.set(new B1());
B1 b = a.getB();

2 行目で、これを行った場合a.set(new B2())、コンパイル時エラーになることに注意してください。コンパイラは、aが にパラメータ化されていると文句を言うB1ため、 a をそれに渡すことはできませんB2。非常に高いレベルでは、コンパイラが検索と置換を行ってT、元のクラスをB1. そして、宣言した場合:

A<B2> a = new A<B2>();

次に、検索と置換も同様に に変わりTますB2

実際には、消去と呼ばれるものがあるため、それほど単純ではありません。詳細についてはJava Trail on genericsを参照してください。他にも多くのリソースが利用可能です。この PDFは、中級レベルの説明に適しています。

于 2013-09-07T06:25:16.950 に答える
1

キャストせずに以下のようにすることもできます。

B b1 = a.getB();
于 2013-09-07T06:13:56.073 に答える
0

ダウンキャストを実行するときは、キャストを明示的に追加する必要があります。アップキャストは暗黙的であり、常に安全なものです。また、明示的に B1 または B2 にキャストする必要があるのはなぜですか。代わりに、キャストを追加する必要のないオブジェクト (つまり B) への参照として、基本インターフェイス タイプを使用できます。

また、実際のオブジェクト型を気にする必要がなく、実行時に ClassCastException を防ぐことができるため、基本参照型は安全です。

オブジェクトへの参照として基本型を使用すると、多くの利点があります。

  • 実行時に ClassCastException を回避します。
  • キャストの追加について心配する必要はありません
  • また、基本クラス階層にさらにクラスを追加した場合でも、基本参照型でこれらのクラスにアクセスできます。これにより、設計がより柔軟になります。
于 2013-09-07T06:16:18.660 に答える
0
public class Test {
    public static void main(String[] args) {
        B b = new B1();
        if(B1.class.getName().equals(b.getClass().getName())){
            // implement logic for B1 class
        }else if(B1.class.getName().equals(b.getClass().getName())){
            // implement logic for B2 class         
        }
    }
}

interface B{    
}

class B1 implements B{  
}

class B2 implements B{  
}

また

メソッドのオーバーライドを行うと、さまざまなクラスにさまざまなロジックを実装でき、キャストなしでインターフェース参照を使用してメソッドを呼び出すことができます

于 2013-09-07T06:24:25.180 に答える