まず、用語の明確化: Child
type の変数にオブジェクトを代入していますParent
。のサブタイプであるParent
オブジェクトへの参照です。Parent
Child
これは、より複雑な例でのみ役立ちます。getEmployeeDetails
クラス Parent に以下を追加するとします。
public String getEmployeeDetails() {
return "Name: " + name;
}
そのメソッドをオーバーライドして、Child
詳細を提供できます。
@Override
public String getEmployeeDetails() {
return "Name: " + name + " Salary: " + salary;
}
Parent
これで、オブジェクトが であるかであるかに関係なく、利用可能な詳細を取得する 1 行のコードを記述できますChild
。
parent.getEmployeeDetails();
次のコード:
Parent parent = new Parent();
parent.name = 1;
Child child = new Child();
child.name = 2;
child.salary = 2000;
Parent[] employees = new Parent[] { parent, child };
for (Parent employee : employees) {
employee.getEmployeeDetails();
}
出力は次のようになります。
Name: 1
Name: 2 Salary: 2000
を として使用しChild
ましたParent
。Child
クラスに固有の特別な動作がありましたが、呼び出したときに違いを無視して、どのように とが似ているgetEmployeeDetails()
かに焦点を当てることができました。これをサブタイプ多型と呼びます。Parent
Child
あなたの更新された質問は、オブジェクトが参照に格納されているChild.salary
ときにアクセスできない理由を尋ねます。答えは、「ポリモーフィズム」と「静的型付け」の交差点です。Java はコンパイル時に静的に型付けされるため、コンパイラから一定の保証が得られますが、代わりにルールに従うことを余儀なくされます。そうしないと、コードがコンパイルされません。ここで、関連する保証は、サブタイプ (例: ) のすべてのインスタンスがそのスーパータイプ (例: ) のインスタンスとして使用できるということです。たとえば、型の変数に割り当てることができる null 以外のオブジェクトにアクセスするか、メソッドまたはフィールドが定義されていることが保証されます。Child
Parent
Child
Parent
employee.getEmployeeDetails
employee.name
employee
Parent
. この保証を行うために、コンパイラは、Parent
アクセスできるものを決定するときに、静的な型 (基本的には変数参照の型) のみを考慮します。そのため、オブジェクトの実行時型で定義されているメンバーにはアクセスできませんChild
。
Child
本当に a を aとして使用したい場合、Parent
これは簡単な制限であり、コードはParent
およびそのすべてのサブタイプで使用できます。それが受け入れられない場合は、参照の型を作成しますChild
。