Javaでのポリモーフィズムとダウンキャスト
記事の内容は、java8環境を使用してShangシリコンバレーから選択されています
Javaオブジェクト参照の詳細な説明
:Javaの多型の詳細については、以前のブログを参照してくださいJavaの多型を。
package com.atguigu.java4;
public class Person {
String name;
int age;
int id = 1001;
public void eat(){
System.out.println("人吃饭");
}
public void walk(){
System.out.println("人走路");
}
}
package com.atguigu.java4;
public class Man extends Person {
boolean isSmoking;
int id = 1002;
public void earnMoney(){
System.out.println("男人挣钱");
}
public void eat(){
System.out.println("男人吃饭");
}
public void walk(){
System.out.println("男人走路");
}
}
package com.atguigu.java4;
public class Woman extends Person {
boolean isBeauty;
public void eat(){
System.out.println("女人吃饭");
}
public void walk(){
System.out.println("女人走路");
}
public void goShopping(){
System.out.println("女人爱逛街");
}
}
コードが実行されるとき
Person p2 = new Man();
図に示すように、Javaポリモーフィズムでオブジェクト属性のメモリを分析する場合、
p2はManオブジェクトのヒープスペースアドレスを指しますが、p2がサブクラスの一意の属性を呼び出すことはできません。
// p2.isSmoking = True;
このようにコンパイラを記述すると、エラーが報告されます。分析により、p2が指すヒープスペースオブジェクトにはisSmoking属性が含まれていますが、このオブジェクトは結局Manオブジェクトであり、属性を付けることはできません。つまり、p2は呼び出すことしかできません。宣言された型のメソッドと属性。
親クラスの参照は、子クラスのプロパティを呼び出します(ダウンキャスト)
ただし、親クラスの参照(p2)でサブクラス(isSmoking)のプロパティを呼び出す必要がある場合は、強制型変換を使用する方法もあります。
package com.atguigu.java4;
public class PersonTest {
public static void main(String[] args) {
Person p1 = new Person();
Person p2 = new Man();
p2.eat();
System.out.println(p2.id);
// p2.isSmoking = True;
Man m1 = (Man)p2;
m1.isSmoking = true;
m1.earnMoney();
System.out.println(m1.isSmoking);
}
}
このようにして、サブクラスのプロパティを呼び出すことができ、操作の結果は次のようになります。
男性は
1001
人を食べ
ます男性は本当のお金を稼ぎます
ただし、そのメモリ構造では、スタックスペースのm1変数とp2変数はすべて、同じManオブジェクトのアドレス値を指しますが、m1はManタイプとして宣言されているため、m1はヒープスペースサブクラスのメソッドとプロパティを呼び出すことができます。また、p2はPersonクラスとして宣言されており、親クラスのメソッドとプロパティのみを呼び出すことができます。
基本的なデータ型の強制型変換と自動型昇格を比較してください。
次の図は、Shang Silicon Valleyの図を直接採用しています。
ただし、強制型変換は気軽に使用できません。コンパイラがエラーを報告しない場合がありますが、ClassCastException型動作中に変換例外が発生します。
package com.atguigu.java4;
public class PersonTest {
public static void main(String[] args) {
Person p2 = new Man();
Man m1 = (Man)p2;
m1.isSmoking = true;
Woman w1 = (Woman)p2;
w1.goShopping();
}
}
操作の結果は次のとおりです。
スレッド「main」の例外java.lang.ClassCastException:com.atguigu.java4.Man
をcom.atguigu.java4.PersonTest.main(PersonTest.java:8)のcom.atguigu.java4.Womanにキャストできません。
これは、p2自体が指すヒープスペースにgoshoppingメソッドがない
ためです。したがって、変換を確実に成功させるために、型変換の実行時にinstanceofキーワードが導入されます。
instanceofキーワードの使用法
- 使用法はAのインスタンスであり、オブジェクトがクラスAのインスタンスであるかどうかを判別し、そうである場合はtrueを返し、そうでない場合はfalseを返します。
- instanceof Aがtrueを返し、BがAの親である場合、instanceofBもtrueを返します。
コードは以下のように表示されます
package com.atguigu.java4;
public class PersonTest {
public static void main(String[] args) {
Person p2 = new Man();
if(p2 instanceof Woman){
Woman w1 = (Woman)p2;
w1.goShopping();
System.out.println("***woman****");
}
if(p2 instanceof Man){
Man m1 = (Man)p2;
m1.earnMoney();
System.out.println("***man****");
}
}
}
操作の結果は次のとおりです。
男はお金を稼ぐ
男*
Manのp2インスタンスに特に重点を置いているのは、p2が指すヒープスペースオブジェクトがManオブジェクトで
あるかどうかを確認することです。
Person p2 = new Man();
ポリモーフィズムを使用する場合、ヒープスペースを指すp2クラスのManオブジェクトが宣言されているため、Manのp2インスタンスの戻り値はtrueです。このようにして、サブクラスのメソッドとプロパティが強制的な型変換によって親クラスの参照から呼び出されたときに発生するClassCastException型変換例外が回避されます。