👌

【TypeScript勉強記】:TypeScriptでオブジェクト指向開発

2023/02/20に公開

学習素材

【日本一わかりやすいTypeScript入門】TypeScriptで学ぶオブジェクト指向開発

オブジェクト指向とは

オブジェクト指向とは、再利用のための仕組み

基本情報

3つの役割

  1. ある機能についてのデータと振る舞いをまとめる
  2. 外部から参照・改変できないようにする
  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