継承
- スーパークラスで
abstract
として宣言されているメンバー関数は、サブクラスでoverride
キーワードを使って定義する必要がある。この演習では
Train
クラスを無視し、Locomotive.makeSound
とRailwayCar.makeSound
は次のプログラムのように実装できる。import std.stdio;
import std.exception;

class RailwayVehicle {
 void advance(size_t kilometers) {
 writefln("The vehicle is advancing %s kilometers",
 kilometers);

 foreach (i; 0 .. kilometers / 100) {
 writefln(" %s", makeSound());
 }
 }

 abstract string makeSound();
}

class Locomotive : RailwayVehicle {
 override string makeSound() {
 return "choo choo";
 }
}

class RailwayCar : RailwayVehicle {
 // ...

 override string makeSound() {
 return "clack clack";
 }
}

class PassengerCar : RailwayCar {
 // ...
}

class FreightCar : RailwayCar {
 // ...
}

void main() {
 auto railwayCar1 = new PassengerCar;
 railwayCar1.advance(100);

 auto railwayCar2 = new FreightCar;
 railwayCar2.advance(200);

 auto locomotive = new Locomotive;
 locomotive.advance(300);
}
- 次のプログラムは、
Train
のコンポーネントの音を組み合わせて、Train
自体の音を生成する。import std.stdio;
import std.exception;

class RailwayVehicle {
 void advance(size_t kilometers) {
 writefln("The vehicle is advancing %s kilometers",
 kilometers);

 foreach (i; 0 .. kilometers / 100) {
 writefln(" %s", makeSound());
 }
 }

 abstract string makeSound();
}

class Locomotive : RailwayVehicle {
 override string makeSound() {
 return "choo choo";
 }
}

class RailwayCar : RailwayVehicle {
 abstract void load();
 abstract void unload();

 override string makeSound() {
 return "clack clack";
 }
}

class PassengerCar : RailwayCar {
 override void load() {
 writeln("The passengers are getting on");
 }

 override void unload() {
 writeln("The passengers are getting off");
 }
}

class FreightCar : RailwayCar {
 override void load() {
 writeln("The crates are being loaded");
 }

 override void unload() {
 writeln("The crates are being unloaded");
 }
}

class Train : RailwayVehicle {
 Locomotive locomotive;
 RailwayCar[] cars;

 this(Locomotive locomotive) {
 enforce(locomotive !is null,
 "Locomotive cannot be null");
 this.locomotive = locomotive;
 }

 void addCar(RailwayCar[] cars...) {
 this.cars ~= cars;
 }

 override string makeSound() {
 string result = locomotive.makeSound();

 foreach (car; cars) {
 result ~= ", " ~ car.makeSound();
 }

 return result;
 }

 void departStation(string station) {
 foreach (car; cars) {
 car.load();
 }

 writefln("Departing from %s station", station);
 }

 void arriveStation(string station) {
 writefln("Arriving at %s station", station);

 foreach (car; cars) {
 car.unload();
 }
 }
}

void main() {
 auto locomotive = new Locomotive;
 auto train = new Train(locomotive);

 train.addCar(new PassengerCar, new FreightCar);

 train.departStation("Ankara");
 train.advance(500);
 train.arriveStation("Haydarpaşa");
}
出力:
乗客が乗車している 木箱が積み込まれている アンカラ駅を出発 車両は500キロメートル進んでいる チューチュー, カチャカチャ, カチャカチャ チューチュー, カチャカチャ, カチャカチャ チューチュー, カチャカチャ, カチャカチャ チューチュー, カチャカチャ, カチャカチャ チューチュー, カチャカチャ, カチャカチャ ハイダルパシャ駅に到着 乗客が降車している 荷物が積み降ろされている