お品書き
- 参照型の型変換って?
- キャストするパターン
- 型変換Sample
以前復習した基本データ型の型変換↓
基本データ型はint型とかdouble型のように数値を扱えるようにまとめられている。
そのデータ型間で型の変換ができるという話。
◆参照型の型変換って?
参照型の型変換ができるときというのは、
型変換する前のクラスと変更後のクラスの間で継承関係にあるとき
継承関係にあるクラス同士でオブジェクトの型変換↓
スーパー = サブ のときは自動
サブ = スーパーのときはキャストで明示
イメージ図
1,Stidentクラスでdisplayメソッドをオーバーライドしている。
2,サブクラス独自のメソッドとしてchgStuNoメソッドを持っている
上記を踏まえてSample
Student stu1 = new Student(..); //オブジェクトの生成
Person psn = stu1; //インスタンスのアドレス値が代入される
Student stu2 = (Student)psn; //右辺でキャストして型変換
stu1領域はStudentのインスタンスの領域を指し示す変数
psn領域はstu1の値(アドレス値)をコピーする。
同じインスタンスを指し示す。
psnはPersonクラスの変数のため、見れる領域はPersonの情報のみとなる。
stu1はStudentの情報をすべて扱えるが、psnはPersonクラスの変数のため、Personクラスの情報のみ
指し示す場所が微妙に違うのを注意。
そのため、StudentクラスからPersonクラスは自動で型変換が可能。
キャストするパターン
psnの値がstu2にコピーされる
一般的にはPersonクラスの変数からStudentクラスの変数に変換したときにメモリ上に情報があるとは限らない。
そのため、PersonクラスからStudentクラスに型変換しようとするときにエラーを出す。
変換しても問題ないことをコンパイラーに教えるために、キャストして教える。
Student stu1 = new Student(..); //オブジェクトの生成
Person psn = stu1; //インスタンスのアドレス値が代入される
Student stu2 = (Student)psn; //右辺でキャストして型変換
psn.display(); //➡オーバーライド有効
psn.chgStuNo(...); //➡コンパイルエラー
stu2.chgStuNo(...); //➡OK
サブクラスの変数をスーパークラスの変数に代入は自動
※サブクラスの中には必ずスーパークラスの情報があるため。
スーパークラスの情報をサブクラスの変数に代入するときはインスタンスの中から外を見に行くことになるので、メモリ上に欲しい情報があるとは限らない。
メモリ上にはサブクラスの情報があるのをコンパイラに知らせるために明示的にキャストする必要がある。
◆型変換Sample
public class Person5{
private String name;
public Person5(String name){
this.name = name;
}
public void display(){
System.out.println("名前:" + name);
}
}
public class Student5 extends Person5{
private int stuNo;
public Student5(String name, int stuNo){
super(name);
this.stuNo = stuNo;
}
public void display(){
super.display();
System.out.println("学籍番号:" + stuNo);
}
public void chgStuNo(int stuNo){
this.stuNo = stuNo;
}
}
public class StuSample5{
public static void main(String[] args){
Student5 stu1 = new Student5("大輔",1);
Person5 psn = stu1;
psn.display();
// psn.chgStuNo(1001); コンパイルエラー
/* 補足:instanceofキーワード
オブジェクトのクラスを特定する
対象オブジェクト instanceof クラス名 */
if(psn instanceof Student5){ //Student5クラスのインスタンスかどうか?trueかfalse
Student5 stu2 = (Student5)psn;
stu2.chgStuNo(1001);
stu2.display();
}
}
}
C:\Java\1>java StuSample5
名前:大輔
学籍番号:1
名前:大輔
学籍番号:1001
ちなみに、psnからメソッドを呼び出し、キャストをつけないとどうなるか。
public class StuSample5{
public static void main(String[] args){
Student5 stu1 = new Student5("菅原",1);
Person5 psn = stu1;
psn.display();
psn.chgStuNo(1001); //psnからメソッドを呼ぶとコンパイルエラー
if(psn instanceof Student5){
// Student5 stu2 = (Student5)psn;
Student5 stu2 = psn;
//キャスト演算子をつけないとどうなるか
stu2.chgStuNo(1001);
stu2.display();
}
}
}
C:\Java\1>javac StuSample5.java
StuSample5.java:6: エラー: シンボルを見つけられません
psn.chgStuNo(1001);
^
シンボル: メソッド chgStuNo(int)
場所: タイプPerson5の変数 psn
StuSample5.java:12: エラー: 不適合な型: Person5をStudent5に変換できません:
Student5 stu2 = psn;
^
エラー2個