mi_l さんが書きました:それでは、拡張といってもスーパークラスにあるコンストラクタやメソッドの中にサブクラスでオーバーライドして変数などを増やすという意味になるのでしょうか?
今後の拡張や使い方により上記のようにしないとまずい場合もあります(下でバスを追加した例を挙げてます)
レースカーにしかないものの場合はmi_lさんの最初のようにRaceCarクラスでのみ拡張すればいいです。
(たとえばレースカーだけニトロを積んでるとか(ぉ))
例として今は車に属する(Carクラス)、レースカー(RaceCarクラス)だけですが、たとえばバス(Busクラス)を新しく定義するとします。
コード:
class Car
{
protected int num;//サブクラスから直接アクセスできるようprotectedに変更
public Car()
{
System.out.println("車作成");
}
public Car(int n)
{
num = n;
System.out.println("ナンバーは" + n +"にしました");
}
public void setCar(int n)
{
num = n;
}
public int getCar(){ return this.num; }//ナンバーを参照できるように追加
//オーバーロードしないと何もできない
public void setRace(int c)
{
System.out.println("未実装です");
}
public void show()
{
System.out.println("ナンバー" + num + "の車を作成しました");
}
}
class Bus extends Car
{
public Bus()
{
System.out.println("バスの作成");
}
public void setRace(int c)
{
System.out.println("バスはレースには参加できません");
}
public void show()
{
System.out.println("ナンバー" + num + "のバスを作成しました");
}
}
Carクラス自体にも少し手を入れていますが、これでバスクラスができました。
では、レースカーとバスでレース準備をさせてみましょう。
コード:
class kazuate
{
public final static int MAX_CARS_NUM = 2;//最大台数
public static void main(String[] args)
{
Car cars[] = new Car[kazuate.MAX_CARS_NUM];//Carクラスの配列を定義
cars[0] = new RaceCar();//第1コース・・レースカー
cars[1] = new Bus();//第2コース・・バス
//各車のレース準備
for(int i=0;i < cars.length;i++){
cars[i].setRace(1);
}
}
}
上記のようにすると車の種類が増えたとしても、配列のサイズ拡張と新しい種類の車クラスを宣言するだけで
レース準備のところは手を入れる必要がありません。
CarクラスにsetRaceメソッドの定義がないと上記のような呼び出し方はできなくなってしまいます。
考え方として車ならばレース準備はできるはず、ただしその方法は車の種類によって様々だから(スーパークラスで一律で定義できないから)
各車で改めて定義してもらう(サブクラスでオーバーライドしてもらう)ということになります。
mi_l さんが書きました:それとも、RaceCar cars = new RaceCar();にすればCarクラスを継承し、尚且つ、RaceCarクラスで新たにでたメソッドにも値が渡せるようになるのでしょうか?
今回の件についていえば上記でも動くことは動きます。
ただし、バスやF1カー、その他別の種類の車を新しく追加した際に、setRaceメソッドがあるクラスと無いクラスで処理を別々にしないとならなくなります。
変数も種類ごとに作ることになるので100種類の車ができると管理が煩雑になります。
どうしてもCarクラスの変数を使って実現したいのであればキャストを使うことで一時的にRaceCarクラスとしてふるまわせることもできます。
が、他の種類の車が増えるとやはりだめになります(carsがBusクラスのオブジェクトを参照している場合にはキャスト部分でRaceCarクラスにキャストはできないとエラーになります)
コード:
public static void main(String[] args)
{
Car cars = new RaceCar();
//Car cars = new Bus(); //これだと実行時エラー
((RaceCar)cars).setRace(1);//RaceCarクラスにキャストして一時的にRaceCarとして振る舞わせる
}
長文の割に説明下手ですみません(´・ω・`)