第10回 解答例
Deviceクラス構造を考える
演習の解答例。まず自分で書いてから読むこと。
共通部分を見つける
LED / Motor / Servoに共通するものを書き出すと、次の2つが残る。
- ピン番号を持つ
- 使う前に初期化(
begin())が必要
個別の機能(on() / setSpeed() / setAngle())は共通ではないので、親クラスには置かない。
Device
#pragma once
class Device {
public:
Device(int pin);
void begin();
int getPin() const;
protected:
int pin; // 派生クラスから使いたいので protected
};#include <Arduino.h>
#include "Device.hpp"
Device::Device(int pin)
: pin(pin) {
}
void Device::begin() {
pinMode(pin, OUTPUT);
}
int Device::getPin() const {
return pin;
}派生クラス
#pragma once
#include "Device.hpp"
class LED : public Device {
public:
LED(int pin);
void on();
void off();
void toggle();
private:
bool state;
};#include <Arduino.h>
#include "LED.hpp"
LED::LED(int pin)
: Device(pin), state(false) { // 親のコンストラクタを先に呼ぶ
}
void LED::on() {
state = true;
digitalWrite(pin, HIGH); // 親の protected メンバを使える
}
void LED::off() {
state = false;
digitalWrite(pin, LOW);
}
void LED::toggle() {
if (state) {
off();
} else {
on();
}
}is-aで確認する
| 関係 | 自然に言えるか | 判断 |
|---|---|---|
| LED is a Device | 言える | 継承してよい |
| Motor is a Device | 言える | 継承してよい |
| Servo is a Device | 言える | 継承してよい |
| Robot is a Motor | 言えない | 継承しない |
| Robot has a Motor | 言える | メンバとして持つ |
この設計の限界
Deviceは共通の実装をまとめただけで、「すべてのDeviceが必ず持つべき操作」を強制してはいない。「共通の約束ごと」を決めたい場合は、第12回の抽象クラスを使う。