右は、『 Recoed2クラスを継承したRecord3のクラスがある』というのクラス図です。 |
![]() |
以下にRecord3.javaのコードを示します。
同じrecパッケージ指定なので、
Recoed3.javaも、Record2.javaと同じrecディレクトリの中に作ります。
次のようにRecord3のクラスを作る時、extends キーワードの後にRecord2を指定します。これで、
Record2を継承したクラスになります。
そして、新たにpublic のフィールドとしてint型のtankaを宣言するだけです。
package rec;
public class Record3 extends Record2
{
public int tanka; //単価
}
なお、rec以外のpackageに所属させることもできますが、ここでは同じにしました。
これによりに先頭で、import rec.Record2;の記述が不要になります。
(他のpackageに所属させる場合は必要になります。)
以下のプログラムで、Record3クラスを利用例を示します。(右が実行結果です。)
import rec.Record3;
public class Test
{
public static void main(String[] arg){
Record3 r1 = new Record3();
//レコード2のコンストラクタが内部で実行されいる。
r1.init("A01", 10);//Record2の機能を利用
r1.tanka = 100;
r1.display(1);//Record2の機能を利用
System.out.printf("\t単価:%d\n", r1.tanka);
}
}
|
D:\java>java Test
1番目レコード
商品コード:A01
数量:10
単価:100
D:\java>
|
さて、
上記 の2行は、
Record3専用のinitメソッドを作ることで1行で済ませることができます。
同様に上記 の2行は、
Record3専用のdisplayメソッドを作ることで1行で済ませることができます。
以下で、そう変更したRecoed3.javaとクラス図を示します。
package rec;
public class Record3 extends Record2
{
public int tanka; //単価
public void init(String shoCode, int n, int price)
{
super.init(shoCode, n);// スーパークラスのinitを呼び出す
//この場合はsuperを省略できます
tanka = price;
}
public void display(int n)
{
super.display(n);// スーパークラスのdisplayを呼び出す
//この場合はsuperを省略でません。省略すると、
//自身を呼び出す(再帰)ため無限ループなり、
//StackOverflowErrorの実行エラーになる
System.out.printf("\t単価:%d\n", tanka);
}
}
|
![]() |
Record3でメソッドを追加していますが、
その場合でもなるべくスーパークラスであるRecord2の機能を利用するように作成しています。
メソッドの中で、得にスーパークラスのメソッドを明示的に使いたい場合は、super
のキーワードを使います。このsuperキーワードを使わなくても、同じ操作(引数や戻りなど)のメソッドがなければ、
引き継いでいるスーパークラスのメソッドが使えます。
initの場合は、引数2つのinitメソッドが
Record3に無いので、super.は書かなくてもRecord2のinitメソッドが呼び出せます。
( this.init(shoCode, n)と書いた場合も同じで、Record2のメソッド呼び出しになります。)
対して、displayは全く同じ操作(引数や戻りなど)のメソッドがあるので、明示的に
super
のキーワードを使わないと、Record2の機能が呼び出せないことになります。
以下のこのクラスを使うように変更したTest.javaと実行結果を示します。
import rec.Record3;
public class Test
{
public static void main(String[] arg){
Record3 r1 = new Record3();
//レコード2のコンストラクタが内部で実行されいる。
r1.init("A01", 10, 100);//Record3の機能を利用
r1.display(1);//Record3の機能を利用
}
}
|
D:\java>java Test
1番目レコード
商品コード:A01
数量:10
単価:100
D:\java>
|
なお、 上記のプログラムを、次のように実行できるようにするには どうしたらよいでしょうか?
import rec.Record3;
public class Test
{
public static void main(String[] arg){
Record3 r1 = new Record3("A01", 10, 100);
r1.display(1);//Record2の機能を利用
}
}
シンボルを見つけられません。
シンボル: コンストラクタ Record3(java.lang.String,int,int)
new Record3("A01", 10, 100);の所でコンパイルエラとなります。
つまりRecord3のコンストラクタを追加すればよいのです。
Record3.javaに次のコードを追加すればよいでしょう。
public Record3(String shoCode, int n, int price)
{
super(shoCode, n); // スーパークラスのコンストラクタを呼び出し
tanka = price;
}
派生クラスのコンストラクタから、 そのスーパークラス(派生元クラス)のコンストラクタを呼び出す場合は、 上記のように、コンストラクタ内の { 内先頭行で super( 引数 )の 表現で書かなければいけない規則になってます。
また、上記引数ありコンストラクタを作った時より、デフォルトコンストラクタが
使えなくなります。
つまり、new Record3()のような生成ができなくなります。
これは、Record3.javaに次の引数なしコンストラクタのコードを追加することで可能になります。
public Record3()//引数なしコンストラクタ
{
//スーパ(Recoed2)クラスのコンストラクタ書いていなくても実行される。
}
なお、上記の引数なしコンストラクタや、引数ありコンストラクタで明示的にスーパクラスのコンストラクタを
呼びださない場合は、
書いていなくても自動的にスーパクラスの引数なしコンストラクタが呼び出される
仕組みになっています。
よって この場合、
スーパクラスのRecord2の引数なしコンストラクタが使えるように作られていないと
コンストラクタでシンボルを見つけられません。の
コンパイルエラーとなり、注意が必要です。
以上のメソッドやコンストラクタ追加により、Record3のクラス図は次のようになります。