👌
【TypeScript勉強記】:(自分用)TypeScriptでオブジェクト指向開発
学習素材
【日本一わかりやすいTypeScript入門】TypeScriptで学ぶオブジェクト指向開発
オブジェクト指向とは
オブジェクト指向とは、再利用のための仕組み
基本情報
3つの役割
- ある機能についてのデータと振る舞いをまとめる
- 外部から参照・改変できないようにする
- 同じ機能を持つインスタンスを量産できる
用語
用途 | |
---|---|
プロパティ | クラスが持つデータ(メンバ変数、フィールドとも呼ばれる) |
メソッド | クラスで宣言する関数 |
コンストラクタ | クラスからインスタンスを作るときに行う初期化 |
インスタンス | クラスから作られたオブジェクト。クラスの機能を持つクローン |
将棋をモデル化する
クラスを定義
class Game {} // 将棋のゲーム
class Piece {} // 将棋の駒
class Position {} // 駒の位置
extendsを使って、Pieceクラスの機能を拡張して、各駒の役割・機能を作る。
class Osho extends Piece {}
class Hisha extends Piece {}
class Kaku extends Piece {}
class Kin extends Piece {}
class Gin extends Piece {}
class Keima extends Piece {}
class Kyosha extends Piece {}
class Fu extends Piece {}
駒の位置をクラスにする
型エイリアスを宣言
type Suji = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 // 横
type Dan = '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' // 縦
駒の位置を表すクラスを宣言。
class Position {
// コンストラクタでsuji, danに初期値が作られたら、何かしらの処理がきでる
constructor(
private suji: Suji,
private dan: Dan
) {}
}
インスタンス生成。
new Position(1, '2')
用途 | |
---|---|
private | そのクラスとサブクラスでのみアクセス可能 |
protected | そのクラスとサブクラスでのみアクセス可能 |
public(default) | どこからでもアクセスできる |
将棋の駒のインスタンス
abstract class Piece {
protected position: Position
constructor(
private readonly player: Player,
suji: Suji,
dan: Dan
) {
// this:`Pieceクラスの中のposition
this.position = new Position(suji, dan)
}
// メソッドの定義
// 指定された位置に駒を移動するメソッド
// publicなので、サブクラスで上書きできる
moveTo(position: Position) {
this.position = position
}
// 移動できるかどうかのメソッド
// 駒が移動できる範囲は、駒の種類によって違うので、abstract
// 具体的な実装は、サブクラスで
abstract canMoveTo(position: Position, player: Player): boolean
}
*注* 抽象クラスはインスタンス化できない
抽象クラスは、サブクラスを作るためのクラスであるため、abstractがついた抽象クラスは、インスタンスにできない。
// Cannot create an instance of an abstract class.
new Piece('first', 1, '1')
直接Pieceクラスから駒を作ると、駒の役割という具体性が持たせるために、Pieceクラスの中に具体的なコードを書いていく必要があるが、その場合クラスが再利用できなくなる。
パラメーターに渡された位置と、現在の位置を比較するメソッドを作る
Positionクラスに作成
class Position {
constructor(
private suji: Suji,
private dan: Dan
) {}
// パラメーターに渡された位置と、現在の位置を比較するメソッド
distanceFrom(position: Position, player: Player) {
if (player == 'first') {
return {
suji: Math.abs(position.suji - this.suji),
dan: Math.abs(Number(position.dan) - Number(this.dan))
}
} else {
// 段(縦の位置)は、正負反転
return {
suji: Math.abs(position.suji - this.suji),
dan: -(Math.abs(Number(position.dan) - Number(this.dan)))
}
}
}
}
駒のサブクラスを宣言
class Osho extends Piece {
// 具体的な実装
canMoveTo(position: Position, player: Player): boolean {
let distance = this.position.distanceFrom(position, player)
// 1マス以内だったら移動できる
return distance.suji < 2 && distance.dan < 2
}
}
Gameクラス:駒を生成・初期化
// 将棋のゲーム
class Game {
private pieces = Game.makePieces()
private static makePieces() {
return [
// 先手
new Osho('first', 5, '1'),
// 後手
new Osho('second', 5, '9'),
...(略)...
]
}
}
Discussion