前回作成したUMLを元に、クラスを実装します。
実際、クラスの関係を作成しただけで中身は決まっていません。
しかし、クラスの関係を作るのが先です。上のリンクにはUMLで作成した大まかなクラス関係図があります。
詳細に関して上の「前回」のリンク先を見てもらえばわかると思います。クラス図を作成してクラス関係を作ることができたらクラス間のやり取りするもの(データ)がある程度見えると思います。
ちなみに、見えなかったらから実装して見てください。
クラスを実装
UMLで示したように、Playerクラスが一番上のクラス(基底クラス)になります。なので下のような実装になります。ソースはGithubにコミットしてあるのでそちらを参照ください。
上のリンク先には、パッケージのルートが関連づけられています。
そして、Playerクラスがあります。
Playerクラス
このクラス(Player)は、ゲームのプレーヤー(PlayerCharactor)が操作するキャラクター、PCが操作するプレーヤー(NoPlayerCharactor)の親クラスになります。
このような形で「継承関係」を作ってやると色々と便利なのです。
Playerクラスには、PalyerCharactorとNoPlayerCharactorに共通する、つまりゲームに登場する全てのキャラクターに共通するもの(HP、MPなど)を定義します。(コードにします。)
しかし、現状では、全てに共通する部分のみが決まっているだけなので上の2クラスは未実装です。(中身がありません)
戦士クラス
戦士クラスは、PlayerCharactorであり、その中にある「戦士」という職業(役)を担うクラスです。
なので、操作ができる必要もありますが、ゲームをプレイする我々には「どんなキャラクターなの?」と、気になります。
なので、その部分を表現するための工夫として、戦士クラスではなく一番親のクラス(Player)に下のようなプロパティを実装しました。
/** 精神を表す */ protected Spirit sprit; /** 肉体を表す */ protected Body body; /** キャラクターの役職(王様etc...) */ protected Role role;
上の3つはクラスですが、「クラスにクラスをもたせてはいけない」というルールはないのでこれはこれで良いのです。UMLで書くと下のようになります。
PlayerCharactorクラスに定義していますが、よくよく考えたら、全てのプレーヤー(PlayerCharactorとNoPlayerCharactor)に必要な情報だと思ったのでPlayerクラスに移動しました。
最終的には、PlayerCharactorクラスを親クラスに、NonPlayerCharactorクラスを作成(PlayerCharactorクラスの子どもとする)ようなクラス関係を作成しました。
オブジェクト指向の良いところ
上に記載したように、オブジェクトとして捉えるところに「オブジェクト指向」の良いところがあります。
間違って(やっていくうちに)自分で定義したものが、「不適切だと思ったら、変更しやすい」というところです。しかし、これを変更しづらく作ることもできます。
つまり、変更したい部分を取り外して、別のものをくっつけるというような修正を行うことができます。
なので「プロパティ(フィールド変数)」をカプセル化してやります。
フィールド変数とGetter, Setterを使用する下のような実装にするということです。
/** 肉体を表す */ protected Body body; /** * @return the body */ public Body getBody() { return body; } /** * @param body the body to set */ public void setBody(Body body) { this.body = body; }
これは、手で実装すると面倒ですが、EclipseなどのIDEを使用してやるとクリック一発で実装できます。自動生成というやつです(笑)
しかし、「精神」とか「肉体」をクラスで表現していこうとするととても難解なものができてしまうので、実装する方向を変えることにしました。それは、テキストRPG
関連ページ
・UMLの書き方
・UMLツール Star UML〜ユースケース図を書いて見た〜
・UMLツール 〜Star UMLを使う〜
今日は、ここまでにしておきます。