24日目②(2025.02.23) 演習問題



お疲れ様です!!

今回は、菅原先生が出してくださった演習問題にて僕が「?」ってなったところをここに書き残しておこうと思います。

演習問題は、3問あって
1問目は抽象クラスを使えるか
2問目はインターフェースを使えるか
3問目はパッケージを理解しているか

という感じで同じお題の中で修正したりしながら理解度をチェックするという形です。

そして、最終的なコードがこんな感じ

public abstract class Vehicle {

public abstract class Vehicle {

protected int crewNum;

public abstract void showCrewNum();
}


public class Taxi extends Vehicle implements Stopable {

public Taxi(int crewNum) {
    this.crewNum = crewNum;
}

public void showCrewNum() {
    System.out.println("タクシー乗客人数: " + crewNum + "名");
}

public void stop() {
    System.out.println("ここで降ります");
}
}


public class Bus extends Vehicle implements Stopable {

public Bus(int crewNum) {
    this.crewNum = crewNum;

}

public void showCrewNum() {
    System.out.println("バス乗客 : " + crewNum + "名");
}

public void stop() {
    System.out.println("次止まります");
}
}


public class Train extends Vehicle {

public Train(int crewNum) {
    this.crewNum = crewNum;
}

public void showCrewNum() {
    System.out.println("電車乗客人数: " + crewNum + "名");
}
}

public interface Stopable {
	void stop() ;

}
package pack;
import せかチャン.*;
import せかチャン.Stopable;
import せかチャン.Taxi;
import せかチャン.Train;
import せかチャン.Vehicle;


public class UseVehicle {

	public static void main(String[] args) {
		// TODO 自動生成されたメソッド・スタブ
		
		Vehicle[] v = new Vehicle[3];
		v[0] = new Taxi(4);
		v[1] = new Train(160);
		v[2] = new Bus(80);
		
		for(int i = 0;i < v.length;i++) {
			v[i].showCrewNum();
			if(v[i] instanceof Stopable) {
				Stopable s = (Stopable)v[i];
				s.stop();
			}
		}
	}
}


【学べた点・僕がまだ理解できてないと感じたところ】

①スーパークラス、サブクラスの中での「crewNum」の宣言・定義の仕方
僕は自分でやった際、スーパークラス「Vehicle」で
protected int crewNum;

public Vehicle(int crewNum){
this.crewNum = crewNum;

として、サブクラスで
public Taxi(int crewNum){
super(crewNum);

としていていました。
これでも処理はできるんでしょうけど、演習問題の条件としてVehicleクラスは
protected int crewNum
としか書かれていなかったので、そこを無視してしまいました。
(コンストラクタを使わないと処理できないと思い込んでました、、、)

(Vehicle)
protected int crewNum;

(サブクラス)
public Taxi(int crewNum){
this.crewNum = crewNUm;

そして、ここで疑問が、、、

「なんでsuper.crewNumじゃなくて、this.なん??」

スーパークラスの変数を参照するんだからsuperじゃないん・・・??

というかなんでthis.でエラーにならないんや、、、

みたいな感じでした。

同じ疑問を思った人が菅原先生の動画コメントで質問していたのでそれを拝見させていただきました。

継承関係にある場合、this.でクラス内にフィールドが無ければ勝手にsuperから探してくれるみたいです。
そして、この場合に拾いたいのは「TaxiのcrewNum」であって「VehicleのcrewNum」ではないので、「this」と表記しているとのことです。

②インターフェースを呼ぶクラスで「implements~」を付け忘れた
何度実行してもimplementsを紐づけた処理がされず頭を抱えていました。
なんと、implementsの付け忘れというケアレスミスでした、、、

③配列の復習ができた

久々に配列が出てきて良い復習になりました!!

④型変換の理解不足

Vehicle[]v = new Vehicle[3]
v[0] = new Taxi(4);
→サブクラスからスーパークラスへの型変換

Stopable s = (Stopable)v[i];
→スーパークラスからサブクラスへ型変換

この2つの型変換のパターンはもう少し復習しておかないとと感じました!!

あと、Vehicle[]v = new Vehicle[3]
のところで、
「なんで抽象クラスなのにインスタンス化できるの!?」

って思っちゃいました、、、

このnewは、配列のnewで配列を定義しているだけなので、インスタンス化は関係なかったのですね、、、


というわけで、明日も楽しんでいこう!!!

コメントを残す