GASを使って学ぶオブジェクト指向〜クラスの継承とポリモーフィズム

image

はじめに

今回の記事は、Google Apps Scriptでポリモーフィズムの挙動がわかるコードを作成してみようという、初心者向けの記事です。 ポリモーフィズム(多態性)とは、同じ名前のメソッドが、異なるクラスで、異なる振る舞いをするという概念です。

今回やること

親となる"Cardクラス"を作成し、そのクラスを継承した子クラス"WaribikiCouponクラス"、"NebikiCouponクラス"、"MemberCardクラス"を作成します。
また、"Cardクラス"を継承しない"MemberCardNotExtendsクラス"を作成します。
これらのクラスを動かす"Casherクラス"を作成して、同じメソッドで違う振る舞いをする確認と、継承クラスと非継承クラスの違いを確認します。

クラスの継承

親クラスの作成

親クラスとなる"Cardクラス"を作成します。抽象クラスで作成したいのですが、javascriptには抽象クラスという概念がないので、通常のクラスで作成します。

class Card {
  constructor(name) {
    this.name = name;
  }

  pay() {
    throw new Error('payメソッドは、サブクラスによってオーバーライドされなければならない');  //継承クラスがメソッドをオーバーライドしない場合、エラーを発生させる
  }
  point(){
    throw new Error('pointメソッドは、サブクラスによってオーバーライドされなければならない'); //継承クラスがメソッドをオーバーライドしない場合、エラーを発生させる
  }
}

子クラスの作成

"Cardクラス"を継承した子クラスとして"WaribikiCouponクラス"、"NebikiCouponクラス"、"MemberCardクラス"を作成します。
子クラス名 extends 親クラス名でクラスを継承できます。親クラスのコンストラクタはsuper()で呼び出すことができます。

class WaribikiCoupon extends Card {
  constructor(name, rate) {
    super(name);
    this.rate = rate;
  }

  pay(total) {
    return total - (total * this.rate);
  }
  point(){
    return 0;
  }
}

class NebikiCoupon extends Card {
  constructor(name, amount) {
    super(name);
    this.amount = amount;
  }

  pay(total) {
    return total - this.amount;
  }
  point(){
    return 0; 
  }
}

class MemberCard extends Card {
  constructor(name, rate, pointRate) {
    super(name);
    this.rate = rate;
    this.pointRate = pointRate;
  }

  pay(total) {
    return total - (total * this.rate);
  }
  point(total) {
    return total * this.pointRate;
  }
}

MemberCardNotExtendsクラス作成

"Cardクラス"を継承しない"MemberCardNotExtendsクラス"を作成します。 継承クラスとの違いを確認するためのクラスです。

class MemberCardNotExtends {
  constructor(name, rate, pointRate) {
    this.name = name;
    this.rate = rate;
    this.pointRate = pointRate;
  }

  pay(total) {
    return total - (total * this.rate);
  }
  point(total) {
    return total * this.pointRate;
  }
}

Casherクラス作成

"Casherクラス"はポリモーフィズムを実行するためのクラスです。

class Casher {
  static check(total, card) {
    const newTotal = card.pay(total);
    const point = card.point(total);

    // Cardクラスの継承クラスのみ実行される
    if (card instanceof Card) {
      console.log(card.name + 'を使ったので,支払いは' + newTotal + '円、ポイントは' + point + 'になります');
    } else {
      console.log("エラー、" + card.name + "は、Cardクラスを継承していません");
    }
  }
}

メイン処理

実行するためのメイン処理です。

function main() {
  // 継承クラスのインスタンス作成
  const coupon1 = new NebikiCoupon("300円引きクーポン", 300);
  const coupon2 = new WaribikiCoupon("1割引きクーポン", 0.1);
  const memberCard = new MemberCard("メンバーカード", 0.05, 0.01);
  // 継承なしクラスのインスタンス作成
  const memberCard2 = new MemberCardNotExtends("メンバーカード2", 0.05, 0.1);

  // Casherクラスの実行
  const teika = 5000;
  Casher.check(teika, coupon1);
  Casher.check(teika, coupon2);
  Casher.check(teika, memberCard);
  Casher.check(teika, memberCard2);
}

instanceof 演算子

instanceof演算子は、オブジェクトが特定のクラスのインスタンスであるかどうかを判定します。

console.log(memberCard instanceof Card); // true
console.log(memberCard2 instanceof Card); // false

実行結果

実行ログ
11:25:25    情報  300円引きクーポンを使ったので,支払いは4700円、ポイントは0になります
11:25:25    情報  1割引きクーポンを使ったので,支払いは4500円、ポイントは0になります
11:25:25    情報  メンバーカードを使ったので,支払いは4750円、ポイントは50になります
11:25:25    情報  エラー、メンバーカード2は、Cardクラスを継承していません
11:25:25    情報  true
11:25:25    情報  false

まとめ

クラスの継承を使ったポリモーフィズムを実装する利点としては以下のようなものがあります。

  • 同じメソッド名で、異なるクラスで異なる振る舞いをすることができる。
  • メソッドのオーバーライドを強制することができる。
  • クラスの再利用性が高まる。

他の子クラスの追加や、親クラスのメソッドの変更などをしてみて確認してみると、クラスの継承とポリモーフィズムの理解が深まると思います。

またJavaScriptは、動的型付け言語になります。静的型付け言語であるjavaなどで同じようなコードを書いてみると、型付けの違いを感じることができるかもしれません。 参考になれば幸いです。

お知らせ

可茂IT塾ではFlutterインターンを募集しています!

可茂IT塾ではFlutterインターンを募集しています!

可茂IT塾ではFlutterインターンを募集しています!可茂IT塾のエンジニアの判断で、一定以上のスキルをを習得した方には有給でのインターンも受け入れています。

Read More
U30可茂ITインターンハッカソン

U30可茂ITインターンハッカソン

12月28,29日開催。2日間でアプリ開発の企画から完成までを目指す!U30可茂ITインターンハッカソンを開催します。

Read More

タグ

Flutter (108)初心者向け (28)イベント (18)Google Apps Script (15)Nextjs (11)可茂IT塾 (8)Firebase (7)riverpod (6)React (6)ChatGPT (5)デザイン (5)新卒 (4)就活 (4)vscode (4)Figma (4)Dart (4)JavaScript (4)お知らせ (4)FlutterWeb (3)Prisma (3)NestJS (3)Slack (3)TypeScript (3)ワーケーション (3)インターン (3)設計 (2)線型計画法 (2)事例 (2)Git (2)Image (2)File (2)Material Design (2)画像 (2)iOS (2)アプリ開発 (2)React Hooks (2)tailwindcss (2)社会人 (2)大学生 (2)RSS (1)Google (1)Web (1)CodeRunner (1)個人開発 (1)Android (1)Unity (1)WebView (1)Twitter (1)フルリモート (1)TextScaler (1)textScaleFactor (1)学生向け (1)supabase (1)Java (1)Spring Boot (1)shell script (1)正規表現 (1)パワーポイント (1)趣味 (1)モンスターボール (1)CSS (1)SCSS (1)Cupertino (1)ListView (1)就活浪人 (1)既卒 (1)保守性 (1)iPad (1)シェアハウス (1)スクレイピング (1)PageView (1)画面遷移 (1)flutter_hooks (1)Gmail (1)GoogleWorkspace (1)ShaderMask (1)google map (1)Google Places API (1)GCPコンソール (1)Google_ML_Kit (1)Vercel (1)Google Domains (1)DeepLeaning (1)深層学習 (1)Google Colab (1)オンラインオフィス (1)オブジェクト指向 (1)クラスの継承 (1)ポリモーフィズム (1)LINE (1)Bitcoin (1)bitFlyer (1)コミュニティー (1)文系エンジニア (1)Freezed (1)permission_handler (1)flutter_local_notifications (1)markdown (1)GlobalKey (1)ValueKey (1)Key (1)アイコン (1)go_router (1)debug (1)datetime_picker (1)Apple Store Connect (1)FlutterGen (1)デバッグ (1)Widget Inspector (1)検索機能 (1)Shader (1)Navigator (1)メール送信 (1)Firebase App Distribution (1)Fastlane (1)Dio (1)CustomClipper (1)ClipPath (1)カスタム認証 (1)アニメーション (1)Arduino (1)ESP32 (1)経験談 (1)フリーランス (1)mac (1)csv (1)docker (1)GithubActions (1)Dialog (1)BI (1)LifeHack (1)ショートカット (1)Chrome (1)高校生 (1)キャリア教育 (1)非同期処理 (1)生体認証 (1)BackdropFilter (1)レビュー (1)getAuth (1)Algolia (1)コンサルティング (1)Symbol (1)

お知らせ

可茂IT塾ではFlutterインターンを募集しています!

可茂IT塾ではFlutterインターンを募集しています!

可茂IT塾ではFlutterインターンを募集しています!可茂IT塾のエンジニアの判断で、一定以上のスキルをを習得した方には有給でのインターンも受け入れています。

Read More
U30可茂ITインターンハッカソン

U30可茂ITインターンハッカソン

12月28,29日開催。2日間でアプリ開発の企画から完成までを目指す!U30可茂ITインターンハッカソンを開催します。

Read More