エンジニア成長日記 swaponQ

コンピュータサイエンス専攻の一般人のブログです。

新・明解 Java 入門 演習 12-1 解答

Hello, Terminal!swaponQです!

今回から「第12章:クラスの派生と多相性」に入ります。

第12章には演習が2題しかありませんが、どちらも非常に重要な内容なのでじっくりいきたいと思います!

今回は演習 12-1 に取り組んでいこうと思います。

  • 演習 12-1

走行距離を表すフィールドと、その値を調べるメソッドを追加した自動車クラスを作成せよ。自動車クラスCar第2版から派生すること。

・Day.java

public class Day {
	private int	year	= 1;		// 年
	private int	month = 1;		// 月
	private int	date 	= 1;		// 日

	//-- コンストラクタ --//
	public Day()                              { }
	public Day(int year)                      { this.year = year; }
	public Day(int year, int month)           { this(year); this.month = month; }
	public Day(int year, int month, int date) { this(year, month); this.date = date; }
	public Day(Day d)                         { this(d.year, d.month, d.date); }

	//--- 年・月・日を取得 ---//
	public int getYear()  { return year; }		// 年を取得
	public int getMonth() { return month; }	// 月を取得
	public int getDate()  { return date; }		// 日を取得

	//--- 年・月・日を設定 ---//
	public void setYear(int year)   { this.year  = year; }	// 年を設定
	public void setMonth(int month) { this.month = month; }	// 月を設定
	public void setDate(int date)   { this.date  = date; }	// 日を設定

	public void set(int year, int month, int date) {			// 年月日を設定
		this.year  = year;			// 年
		this.month = month;			// 月
		this.date  = date;			// 日
	}

	//--- 曜日を求める ---//
	public int dayOfWeek() {
		int y = year;					// 0 … 日曜日
		int m = month;					// 1 … 月曜日
		if (m == 1 || m == 2) {		//  :
			y--;							// 5 … 金曜日
			m += 12;						// 6 … 土曜日
		}
		return (y + y / 4 - y / 100 + y / 400 + (13 * m + 8) / 5 + date) % 7;
	}

	//--- 日付dと等しいか ---//
	public boolean equalTo(Day d) {
		return year == d.year && month == d.month && date == d.date;
	}

	//--- 文字列表現を返却 ---//
	public String toString() {
		String[] wd = {"日", "月", "火", "水", "木", "金", "土"};
		return String.format("%04d年%02d月%02d日(%s)",
										year, month, date, wd[dayOfWeek()]);
	}
}

・Car.java

public class Car {
	private String name;			// 名前
	private int width;			// 幅
	private int height;			// 高さ
	private int length;			// 長さ
	public double x;				// 現在位置X座標
	public double y;				// 現在位置Y座標
	public double fuel;			// 残り燃料
	private Day purchaseDay;	// 購入日

	//--- コンストラクタ ---//
	public Car(String name, int width, int height, int length, double fuel,
				  Day purchaseDay) {
		this.name = name;  		this.width = width;	this.height = height;
		this.length = length;	this.fuel = fuel;		x = y = 0.0;
		this.purchaseDay = new Day(purchaseDay);
	}

	public double getX() { return x; }			// 現在位置X座標を取得
	public double getY() { return y; }			// 現在位置Y座標を取得
	public double getFuel() { return fuel; }	// 残り燃料を取得
	public Day getPurchaseDay() {					// 購入日を取得
		return new Day(purchaseDay);
	}

	//--- スペック表示 ---//
	public void putSpec() {
		System.out.println("名前:" + name);
		System.out.println("車幅:" + width  + "mm");
		System.out.println("車高:" + height + "mm");
		System.out.println("車長:" + length + "mm");
	}

	//--- X方向にdx・Y方向にdy移動 ---//
	public boolean move(double dx, double dy) {
		double dist = Math.sqrt(dx * dx + dy * dy);		// 移動距離

		if (dist > fuel)
			return false;				// 移動できない … 燃料不足
		else {
			fuel -= dist;				// 移動距離の分だけ燃料が減る
			x += dx;
			y += dy;
			return true;				// 移動完了
		}
	}
}

・Odometer.java

public class Odometer extends Car {
  private double odometer = 0;
  public double odometer(double dx, double dy) {
    if (super.move(dx,dy)) {
      double dist = Math.sqrt(dx * dx + dy * dy);
      odometer += dist;
    } else {
      System.out.println("燃料が足りません!");
    }
    return odometer;
  }
  Odometer(String name, int width, int height, int length, double fuel, Day purchaseDay, double odometer) {
    super(name, width, height, length, fuel, purchaseDay);
    this.odometer = odometer;
  }
  void setOdometer(double odmeter) {
    this.odometer = odometer;
  }
}

・OdometerTester.java

import java.util.Scanner;
class OdometerTester {
  public static void main(String[] args) {
    Scanner stdIn = new Scanner(System.in);
    Odometer a = new Odometer("myCar",1885,1490,5220,90.0,new Day(2000,1,1),0);
    a.putSpec();
    while(true) {
      System.out.print("走行しますか?(0...No,1...Yes):");
      if(stdIn.nextInt() == 0) break;
      System.out.println("何km走行しますか?");
      System.out.print("x方向:"); double dx = stdIn.nextDouble();
      System.out.print("y方向:"); double dy = stdIn.nextDouble();
      System.out.println("総走行距離:" + a.odometer(dx,dy) + "km");
    }
  }
}


・実行結果

名前:myCar
車幅:1885mm
車高:1490mm
車長:5220mm
走行しますか?(0...No,1...Yes):1
何km走行しますか?
x方向:30
y方向:40
総走行距離:50.0km
走行しますか?(0...No,1...Yes):1
何km走行しますか?
x方向:50
y方向:60
燃料が足りません!
総走行距離:50.0km
走行しますか?(0...No,1...Yes):0

今回は以上です。お疲れ様でした!

さて、次回は演習 12-2 です。

Goodbye, Terminal… swaponQでした!