0
class Person { void f() {} }
class Student extends Person { void f() {} }

したがって、次のコードを実行すると:

Person p = new Student();
((Person) p).f();

f()変数が Person としてキャストされたときに Student クラスの関数が呼び出されるのはなぜですか? f()だけのときに関数が呼び出される理由は理解していますがp.f()、キャストが正確に何をするのか混乱しているだけだと思います。

4

6 に答える 6

1

サブタイプを Type にいつでも変換できます。このキャストは Java では常に許可されますが、インスタンスはサブタイプであるため、サブタイプ メソッドが実行されます。

詳細については、ここを確認してください。Java では、参照変数のキャストには 2 つのタイプがあります。

  • ダウンキャスト: サブタイプ オブジェクトを参照する参照変数がある場合、それをサブタイプの参照変数に割り当てることができます。これを行うには、明示的なキャストを行う必要があります。その結果、この新しい参照変数を使用してサブタイプのメンバーにアクセスできます。
  • アップキャスト: スーパータイプの参照変数に参照変数を明示的または暗黙的に割り当てることができます。割り当てによって新しい変数のアクセス機能が制限されるため、これは本質的に安全な操作です。

はい、クラス オブジェクト参照をインターフェイス型に割り当てられるようにするには、インターフェイスを直接的または間接的に実装する必要があります。

于 2012-09-06T19:26:24.747 に答える
1

メソッドを呼び出す場合、ploymorphsim により参照型ではなく、常にオブジェクト型で実行されます。

于 2012-09-06T19:28:02.583 に答える
1

これは、オブジェクト指向: ポリモーフィズムの基礎の 1 つです。独自の方法で f() を実行するすべての種類の Person エンティティがあります。これはオブジェクトの実際のインスタンスであり、f() をキャストするものではありません。

于 2012-09-06T19:28:07.857 に答える
1

同じメソッド (Student のメソッド) が、Student を Person にキャストしたかどうかに関係なく呼び出されます。

(サブクラスからスーパークラスへの) 参照のアップキャストは実際の機能を提供しません (実際、一般的に内部的に何もしません)。一方、ダウンキャストは、スーパークラスが指定されたサブクラスのものであると信じていることを JVM に伝え、そうでない場合はキャスト エラーが発生します。

(上記の省略を指摘したことでgefeiの功績を認めます:キャストALSOはコンパイラに型を伝え、コンパイラはこの情報を使用して、オブジェクトが(おそらく)持っているメソッドとフィールドを認識します。これは、 Java プログラムをバイトコードに変換しますが、コンパイラが通常のコンパイル時の有効性チェックを実行できるようにします)。

于 2012-09-06T19:29:25.500 に答える
0

アップキャストはここでは関係ありません。オーバーライドされたメソッドは、存在する場合は常に呼び出されます。

于 2012-09-06T19:28:21.460 に答える
0

あなたの例のキャストはまったく役に立ちません。コンパイラは、それpが の型であることを認識していPersonます。より興味深いのは、キャストを絞り込むことです。

Person p = getPerson();
if (p instanceof Student) {
    Student s = (Student) p;
    // do something Student-specific with s
}

Java で参照型をキャストしても、オブジェクトの性質は変わりません。オブジェクトに関してどのような仮定を行うことができるかをコンパイラに伝えるだけです。実行時に、オブジェクトの実際の型を使用して、呼び出されるメソッドが決定されます。(これはプリミティブ型には当てはまらないことに注意してください。 を にキャストするintbyte、データが変更されます。)

于 2012-09-06T19:30:56.830 に答える