Javaマスターへの道 資格勉強編 Part23
今日は昨日の続きをやっていきますのでまだ見ていない方はこちらから。
昨日のプログラムを一部修正したものを使用していこうと思います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | public class Super { private int id; ---修正箇所2--- private String name; ---修正箇所2--- Super() {}; public Super(int id, String name) { this.id = id; this.name = name; } void getInfo() { System.out.println("id : " + id); System.out.println("name : " + name); } void getInfo(String word) { System.out.println("I am " + word + "desu"); } ---メソッド追加--- void changeInfo(int id, String name) { this.id = id; this.name = name; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | public class Sub extends Super { Sub(int id, String name) { super(id, name); ---修正箇所1--- System.out.println("Set ok"); } public static void main(String[] args) { Super super1 = new Super(1, "takai"); Super a = new Sub(10, "a"); ---変数追加--- Sub sub = new Sub(2, "takasugi"); //Sub b = new Super(20, "b"); why1 ---変数追加--- super1.getInfo(); sub.getInfo(); a.getInfo(); //b.getInfo(); why1 super1.changeInfo(11, "takagi"); sub.changeInfo(21, "takamizawa"); super1.getInfo(); sub.getInfo(); } } |
修正箇所の説明をしていきます。
1、前回のプログラムではコンストラクタでidとnameを初期化していましたが、
あのままではSubクラスのコンストラクタでは初期化できないため、
明示的にsuper(id, name)と指定して初期化を出来るようにしています。
2,アクセス修飾子にprivateを指定して外部クラスからは直接操作できないようにしました。
これはカプセル化と言われていて、以前のブログでも少し紹介していますのでよければこちらから。
修正箇所は以上ですので、ここから本題に入っていこうと思います。
今回のテーマは2つあります。
1つ目はSubクラスの変数追加部分です。
Sub型のインスタンスをSuper型に詰めている変数aと
Super型のインスタンスをSub型に詰めている変数bがありますね。
コードを見るとわかるので結論からお話しますが、
変数aは宣言できますが、変数bはコンパイルエラーとなります。
これは型変換ができないのでエラーになるのですが、少し違和感がありますよね。
例えばint型の変数にlong型のデータの変数を入れるなどの型変換はサイズが大きいほうから小さいほうに
するのでデータが一部損失するため明示的にキャストを書きコンパイルエラーを避けます。
ですが今回の場合はその逆がコンパイルエラーになってしまいます。
なので継承時のクラスのキャストは特殊であることを覚えておきましょう。
2つ目はchangeInfo()メソッドで一度初期化したものを変更する機能を持っています。
このメソッドを挟むことで初期化時に間違えてしまっても、
修正することができるので大変役に立ちそうです。
機能としてはありがたいのですが、データの変更を容易にしてしまうメソッドなどは
あまり推奨はされません。
本来はコンストラクタでのみデータは初期化されるためデータ隠蔽が実現できているのです。
数千行のコードがあった場合に途中のどこかでデータが変更されでもしたら大変ですよね。
そのようなことを防ぐためにもデータを変更するようなメソッドは書くべきではないでしょう。
今日はここまでです。
次回もお楽しみに!