まず、用語の明確化: Childtype の変数にオブジェクトを代入していますParent。のサブタイプであるParentオブジェクトへの参照です。ParentChild
これは、より複雑な例でのみ役立ちます。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()かに焦点を当てることができました。これをサブタイプ多型と呼びます。ParentChild
あなたの更新された質問は、オブジェクトが参照に格納されているChild.salaryときにアクセスできない理由を尋ねます。答えは、「ポリモーフィズム」と「静的型付け」の交差点です。Java はコンパイル時に静的に型付けされるため、コンパイラから一定の保証が得られますが、代わりにルールに従うことを余儀なくされます。そうしないと、コードがコンパイルされません。ここで、関連する保証は、サブタイプ (例: ) のすべてのインスタンスがそのスーパータイプ (例: ) のインスタンスとして使用できるということです。たとえば、型の変数に割り当てることができる null 以外のオブジェクトにアクセスするか、メソッドまたはフィールドが定義されていることが保証されます。ChildParentChildParentemployee.getEmployeeDetailsemployee.nameemployeeParent. この保証を行うために、コンパイラは、Parentアクセスできるものを決定するときに、静的な型 (基本的には変数参照の型) のみを考慮します。そのため、オブジェクトの実行時型で定義されているメンバーにはアクセスできませんChild。
Child本当に a を aとして使用したい場合、Parentこれは簡単な制限であり、コードはParentおよびそのすべてのサブタイプで使用できます。それが受け入れられない場合は、参照の型を作成しますChild。