「オブジェクト指向と得体の知れないモノたち」の続きみたいなハナシ。クラスやオブジェクトをなるべく“ドライに考える”ための練習。クイズだと思っても、実務的ヒントとして受け取っても、どっちでもいいですよ。
この継承は変な感じ
class Point2D { protected double x; protected double y; // コンストラクタ(略) void moveTo(double x, double y) { // ... } // ... 点を操作するいろいろなメソッド } class ColoredPoint2D extends Point2D { protected Color color; // コンストラクタ(略) Color getColor() { return color; } // ... } class Point3D extends Point2D { protected double z; // コンストラクタ(略) // ... }
ColoredPoint2D extends Point2Dはいいのだけど、Point3D extends Point2Dは気持ち悪いんだけど、何故でしょう。([追記]typo直した。[/追記])
こういう型をクラスで定義したいのだけど
- ASCII文字だけからなる文字列 AsciiString
- 非負の整数 NonNegativeInteger
- テストの点数として0から100までの整数 Score100
- 同様に0から1000までの整数 Score1000
JavaのStringやIntegerは継承できませんが、仮に継承できたとして、class AsciiString extends Stringとかclass NonNegativeInteger extends Integerとしてうまく定義できるのでしょうか?
テストの点数は列挙型でなんとかなりそうですが、0点から1000点まで並べる? 10000点までならどうする?
こういう型達の関係は
会員番号もハンドル(ニックネーム)も、どっちでもユーザーIDとして使えるとします。
class UserID { protected int number; protected String handle; // ... }
numberとhandleの両方が同時にセットされることはないことを保証したいのですけど、どうしましょう?
さらに、UserNumberとUserHandleというクラスがあるとして、UserID, UserNumber, UserHandleの間の継承関係はどうしましょうか。
どっちに味方しますか
TextViewerは、その名の通りテキスト閲覧機能を提供するコンポネントのクラスです。TextEditorは編集も可能なクラスです。AさんとBさんの主張が食い違ってます。
- Aさん:
TextEditor extends TextViewerとすべき。 - Bさん:
TextViewer extends TextEditorとすべき。
Aさん「TextViewerに、編集機能を実現するコードを追加してTextEditorを実装するよね。だから、TextEditorがサブクラスに決まってるでしょ。」
Bさん「いや、汎用のTextEditorをまず作っておいて、それを他で利用するんだ。サブクラスであるTextViewerでキーボートイベントのハンドラをdo-nothingにオーバライドするだけでOK」
Aさん「サブクラスで編集機能を追加するんだ!」
Bさん「サブクラスで編集機能をつぶすんだ!」