5

Java には、クラスと、 やなどNumの を拡張するいくつかのクラスがあります。特定のオブジェクトが であるかどうかをメソッドが認識できるかどうかを知りたいです。NumNum_intNum_doubleNumNum_int

次のコードがあります。

void test(Num_int x) {
  System.out.println("int");
} // test
void test(Num x) {
  System.out.println("other");
} // test

Num_int A = new Num_int( );
Num B     = new Num_int( );
Num C     = new Num_double( );

test(A); // prints "int"
test(B); // prints "other"
test(C); // prints "other"

残念ながら、メソッド「test」は、A が引数として与えられた場合にのみ「int」を出力します。B はNum B = new Num_int( );. これは可能ですか?

ありがとう。

4

5 に答える 5

3
if (x instanceof Num_int) {
  System.out.println("int");
} else {
  System.out.println("other");
}
于 2012-12-14T18:10:16.840 に答える
3

ポリモーフィックな動作が必要な場合は、テスト メソッドを Num クラスのオーバーライド可能なメソッドにします。

オーバーロードされたメソッドは、引数の実行時の型に基づいて多態的に解決されません。それらは、宣言された引数の型に基づいて、コンパイル時に解決されます。

于 2012-12-14T18:11:52.457 に答える
2

これは、instanceofオペレーターとキャストを使用して行うことができます。ただし、これは貧弱なプログラミング手法です。

より良いオプションはtest()、非finalメンバーを作成しNum、各クラスで適切にオーバーライドすることです。次に、 を呼び出すだけA.test()で、Java の動的ディスパッチがすべてを処理します。

public class Num {
  public void test() {
    System.out.println("other");
  }
}

public class Num_int extends Num {
  public void test() {
    System.out.println("int");
  }
}

public class Num_double extends Num {
  // inhertis Num.test()
}
于 2012-12-14T18:10:03.760 に答える
1

問題は、メソッド シグネチャが Java のコンパイル時にバインドされるため、宣言された型によって呼び出されるメソッドが決定されることです。

ブックJava Puzzlersのパズル作成者「Making a Hash of It」も参照してください。

二重ディスパッチと訪問者パターンを使用できます。次のようになります。

Num_int A = new Num_int( );
Num B     = new Num_int( );
Num C     = new Num_double( );

Num_printer p = new Num_printer();

A.accept(p);
B.accept(p);
C.accept(p);

Num_int.accept(...)メソッドとメソッドはどちらも次のNum_double.accept(...)ようになります。

public class Num_int extends Num {
    public void accept(Num_visitor v) {
        v.visit(this); // from this scope, `this` has a declared type of `Num_int`
                       // so at compile time this is binded to signature visit(Num_double)
    }
}

public class Num_double extends Num {
    public void accept(Num_visitor v) {
        v.visit(this); // from this scope, `this` has a declared type of `Num_double`
                       // so at compile time this is binded to signature visit(Num_double)
    }
}

これらのメソッドはほとんど同じですが、メソッドが親クラスに抽出されないことが重要です。親クラスで抽象化するところまで行きます:

public class Num {
    public abstract void accept(Num_visitor);
}

class 内からNumthisis は宣言された typeNumです。メソッドがここで定義されている場合accept、コンパイル時のバインディングは署名になりvisit(Num)ます。同じ元の問題が再び発生します。

最後に、は次のNum_printerようになります。

public class Num_printer implements Num_visitor {

    public void visit(Num_int n) {
        System.out.println("int");
    }

    public void visit(Num_double n) {
        System.out.println("double");
    }

}
于 2012-12-14T18:18:01.347 に答える
0

instanceof演算子を使用できます。このドキュメントの「型比較演算子 instanceof」の部分を読んでください。

if (x instanceof Num_int) {
  // do something
} else if (x instanceof Num_double) {
  // do something else
}
于 2012-12-14T18:12:07.170 に答える