0

私には意味が分からないので、継承の基本的なものを見逃していたに違いありません。

次の 2 つのクラスがあるとします。

class Person
{
   private String name;
}

class Student extends Person
{
   private String degree;
}

新しいStudentオブジェクトを作成してPerson型変数に格納し、変数を保持しString degreeてアクセスできるのはなぜですか?

Person p = new Student("John", "Master's");

変数には変数を含めることができないため、p以外の変数を持たないため、これは上記の初期化を使用することが可能であると考えました。namePersondegreedegreep

それが、反対が違法であるという事実の背後にある理由だと私が思ったものです
( Student s = new Person("John");) -sその場合、他の変数 ( degree) が初期化されないためです。

4

2 に答える 2

3

スーパータイプへの参照の型を持つ変数は、サブタイプのインスタンスへの参照を保持できます。サブタイプのインスタンスを変数に割り当てても、インスタンスはまったく変更されません。参照の種類を広げるだけです。すべてのインスタンス データはまだそこにあり、ダウンキャストによって取得できます。あれは、

Student s = new Student("John", "Master's");
Person p = s; // no cast needed for a widening conversion

は次とまったく同じです:

Person p = new Student("John", "Master's");
Student s = (Student) p; // cast required for a narrowing conversion

編集おそらくこれは物事を明確にするのに役立ちます。の 2 番目のサブクラスがあるとしPersonます。

class Teacher extends Person
{
    private String department;
}

今、あなたはこれを行うことができます:

Person p = new Teacher("Fred", "Physics");
Teacher t = (Teacher) p;

ただし、後でこれを実行しようとした場合:

p = new Teacher("Fred", "Physics");
Student s = (Student) p; // Error!

ClassCastExceptionプログラムのその時点で、はではないpオブジェクト ( のインスタンス) への参照になっているため、 が得られます。TeacherStudent

ここに類推があります。英語では、「I have a pet animal」と言うかもしれません。これは動物の種類については何も言いません。(たとえば、ペットが吠えるかどうかはわかりません。) 一方、「私はペットの犬を飼っています」と言う場合、見知らぬ人に吠えるかどうかを尋ねるのは理にかなっています。重要な点は、あなたのペットを動物と呼んでも、それが犬である (またはそうでない) という事実は変わらないということです。Java 参照でもまったく同じことが起こっています。より一般的な (基本クラスなどの) 参照型を使用してオブジェクト参照を格納しても、オブジェクト自体の性質は変わりません。オブジェクトの詳細についての知識は失われますが、それらの詳細はまだそこにあります。

コメントで述べた点を繰り返します。Java ではオブジェクトを変数に割り当てることはありません。オブジェクトへの参照のみを割り当てます。別の言い方をすれば、どの変数もオブジェクトではありません。

于 2012-11-25T19:48:32.917 に答える