TypeScript のクラス

TypeScript のクラス

1. 概要

クラスの概念は、 JavaPythonなど、基本的にすべてのオブジェクト指向プログラミング言語が持っている概念ですJavaScriptでは、ES6以前にはクラスの概念はありませんでした。すべてクラスベースの継承を使用し、クラスを通じてオブジェクトが作成されるため、オブジェクト指向プログラミングに精通しているプログラマーにとっては少しトリッキーです。クラスの概念は ES6 で追加されました。これは単なる構文上の糖衣ですが、プログラマーがクラスに基づいて操作できるようになります。 TS ではクラスの概念もサポートされています。

2. シンプルなクラスを定義する

TS では、class キーワードもクラスの定義に使用されます。サンプル コードは次のとおりです。

;(関数 () {
  // クラスを定義する class Person {
    // パブリック属性。デフォルトでは省略可能。パブリック名: 文字列
    // コンストラクタ コンストラクタ(name: string) {
      // 名前プロパティを初期化します this.name = name
    }
  }
  // クラスをインスタンス化 const person = new Person('Yiwan Zhou')
  console.log(person.name) // 周一万})()

上記で定義したクラスには、コンストラクタとパブリック属性名があります。クラスがインスタンス化されると、コンストラクタが呼び出され、機能属性が初期化されます。

以下のように、上記の省略形もあります。

;(関数 () {
  クラス Person {
    コンストラクター(パブリック名: 文字列) {}
  }
  // クラスをインスタンス化 const person = new Person('Yiwan Zhou')
  console.log(person.name) // 周一万})()

これは上記と同等です。

3. 継承

オブジェクト指向プログラミング言語において、重要な機能の 1 つは継承です。継承とは、特定のクラスに基づいて既存のクラスを拡張することです。

例えば、父親が北京に中庭付きの家を所有している場合、息子は父親の中庭付きの家を相続し、さらに自分用の別荘を購入することもできます。最終的に、息子の財産は北京の中庭付きの家と別荘になります。

TS では、継承には extends キーワードを使用します。サンプル コードは次のとおりです。

;(関数 () {
  // スーパークラスとも呼ばれる基本クラスを定義する class Person {
    // 基本クラスのコンストラクターで名前プロパティを定義します(public name: string) {}
  }
  // 基本クラスから継承する派生クラス(サブクラスとも呼ばれる)を定義します。class Programmer extends Person {
    コンストラクター(名前: 文字列、パブリック趣味: 文字列) {
      // 基本クラスのコンストラクタ super(name) を super 経由で呼び出します
    }
  }
  // サブクラスをインスタンス化します const programmer = new Programmer('一碗周', 'coding')
  console.log(programmer.name, programmer.hobby) // 毎週のコーディングの記録
})()

上記のコード例では、 Personは基本クラスまたはスーパークラスと呼ばれ、 Programmer派生クラスまたはサブクラスと呼ばれます。

上記の例では、 Programmerクラスはextendsキーワードを使用してPersonクラスから継承します。サブクラスには親クラスのすべてのプロパティとメソッドが含まれます。

サブクラスのコンストラクタでは、基本クラスのコンストラクタを実行するためにsuper()メソッドを呼び出す必要があります。これは必須です。

クラス継承では、クラスを継承できるだけでなく、サブクラスで親クラスのプロパティやメソッドをオーバーライドすることもできます。サンプルコードは次のとおりです。

// Personクラスを定義する class Person {
    コンストラクター(パブリック名: 文字列) {}
    // メソッド sayMy() を定義する {
        console.log(`私の名前: ${this.name}`)
    }
}
// Personクラスを継承するAdultクラスを定義する class Adult extends Person {
    コンストラクター(パブリック年齢: 数値) {
        super('向こう側は繁栄している')
    } // 親クラスのメソッド sayMy() をオーバーライドします {
        console.log(`私の名前: ${this.name} 年齢: ${this.age}`)
    }
}
// Adult クラスを継承する Programmer クラスを定義します。class Programmer extends Adult {
    コンストラクタ(public hobby: string) {
        スーパー(18)
    } // 親クラスのメソッド sayMy() をオーバーライドします {
        コンソール.log(
            `私の名前: ${this.name} 年齢: ${this.age} 趣味: ${this.hobby}`
        )
    }
}
// クラスのインスタンス化 const programmer = new Programmer('coding')
programmer.sayMy() // 私の名前: Bi'an Fanhua 年齢: 18 趣味: コーディング

まず、クラスに 1 つの属性と 1 つのメソッドを定義するPersonクラスを定義しました。次に、Person クラスから継承してPersonクラスのメソッドを上書きするAdultクラスを定義しました。最後に、 Adultクラスから継承して Adult クラスのメソッドを上書きするProgrammerクラスを定義しました。つまり、 Programmerクラスには、Person クラスと Adult クラスのすべての属性とメソッドがありますが、sayMe() メソッドは 2 回上書きされているため、 Programmerクラスには 3 つの属性と 1 つのメソッドがあります。

4. public、private、protected 修飾子

public、private、protected 修飾子の違い:

  • public : パブリック。クラスで定義されたメンバーに自由にアクセスできます。 TSはデフォルトでpublicになります
  • private : プライベート、クラス内で定義されたメンバーはクラス外ではなくクラス内でのみアクセスできます。
  • protected : protected、このクラスまたはそのサブクラスで定義されたメンバーにアクセスできます。

サンプルコードは次のとおりです。

// パブリック メンバー、プライベート メンバー、および保護されたメンバーを含む Person クラスを定義します。
クラス Person {
  公開名: 文字列
  // 一般的に、プライベートメンバーは _ private _age: number で始まることが合意されています
  保護された趣味: 文字列
  // プロパティ初期化コンストラクター(name: 文字列、age: 数値、hobby: 文字列) {
    this.name = 名前
    this._age = 年齢
    this.hobby = 趣味
  }
  セイマイ() {
    console.log(this.name、this._age、this.hobby) です。
  }
}

// Person クラスをインスタンス化します const person = new Person('一碗周', 18, 'coding')

console.log(person.name) // 一碗周//クラス外のプライベートメンバーにアクセスすると例外がスローされます// console.log(person._age) // エラーを報告します//クラス外のプロテクトメンバーにアクセスすると例外がスローされます// console.log(person.hobby) // エラーを報告します//クラス内からプライベートメンバーとプロテクトメンバーにアクセスできます person.sayMy() // 一碗周18 コーディング

// Personクラスを継承するクラスを定義する class Programmer extends Person {
  コンストラクター(名前: 文字列、年齢: 数値、趣味: 文字列) {
    スーパー(名前、年齢、趣味)
  }
  セイマイ() {
    console.log(this.name) // 一碗周// 親クラスのプライベートメンバーはサブクラスではアクセスできません // console.log(this._age) // エラーレポート// サブクラスではプロテクトメンバーにアクセスできます console.log(this.hobby) // コーディング
  }
}

// Programmer クラスをインスタンス化します const programmer = new Programmer('一碗周', 18, 'coding')
プログラマー.sayMy()

// 他のコードのメンバーと競合がないことを確認する export {}

上記のコードに示されているように、基本クラスではパブリック メンバー、プライベート メンバー、および保護されたメンバーにアクセスできますが、クラス外ではパブリック メンバーにのみアクセスできます。 Personクラスから継承するサブクラスを定義すると、サブクラス内の保護されたメンバーにはアクセスできますが、プライベート メンバーにはアクセスできません。

4.1ゲッターとセッター

クラス内のプライベート メンバーと保護されたメンバーの読み取りと書き込みが実際には不可能というわけではありません。TS は、オブジェクト メンバーへのアクセスを効果的に制御できるように、 getterssettersを提供します。

サンプルコードは次のとおりです。

// Personクラスを定義する class Person {
  // プライベートメンバーは通常 _ private _name: string で始まることが合意されています
  // プロパティ初期化コンストラクター(名前: 文字列) {
    this._name = 名前
  }
  // プライベート_name属性値を取得する get getName(): string {
    this._name を返す
  }
  // プライベート_nameプロパティ値を設定する set setName(name: string) {
    this._name = 名前
  }
}
// クラスをインスタンス化 const person = new Person('a bowl of porridge')
// getName で取得 console.log(person.getName) // お粥のボウル // setName で _name の値を設定 person.setName = 'お粥のボウル'
// 再取得 console.log(person.getName) // Yiwan Zhou

5. 読み取り専用修飾子

readonly修飾子を使用して、プロパティを読み取り専用に設定できます。読み取り専用プロパティは、宣言時またはコンストラクター内で初期化する必要があります。

サンプルコードは次のとおりです。

// 読み取り専用属性を持つクラスを定義する class Person {
  // 読み取り専用名前: 文字列
  // 同等 // public readonly name: string
  // コンストラクター(名前: 文字列) {
  // this.name = 名前
  // }
  // またはコンストラクタ(public readonly name: string) {}
}
// インスタンス化 const person = new Person('一碗周')
console.log(person.name) // 一碗周// name の値を変更します// person.name = '一碗周' // エラー! name は読み取り専用です。

6. 静的メンバー

TS では静的メンバーを作成することもできます。これらのプロパティまたはメソッドは、クラスのインスタンスではなく、クラス自体に存在します。 TS での静的メンバーの定義は ES6 の場合と同じで、どちらもstaticキーワードを使用して示します。

サンプルコードは次のとおりです。

クラスHero {
  // カウンターの静的カウント = 0
  コンストラクタ(パブリック名: 文字列) {
    // 毎回プロパティカウントを作成します ++
    ++ヒーロー数
  }
}
// Hero クラスをインスタンス化します const hero1 = new Hero('Sun Wukong')
console.log(Hero.count) // 1
const hero2 = 新しい Hero('Nezha')
console.log(Hero.count) // 2

ここでは、静的プロパティを使用して、インスタンス化された複数のクラスを記録するカウンターを実装します。

7. 抽象クラス

抽象クラスとは何かを理解するには、まず抽象化とは何かを理解する必要があります。いわゆる抽象化とは、多くのものか​​ら共通かつ重要な機能を抽出し、重要でない機能を破棄することです。例えば、リンゴ、バナナ、生の梨、ブドウ、桃など、それらの共通の特徴は果物であるということです。果物の概念に到達するプロセスは抽象的なプロセスです。

抽象クラスは、多くのクラスから共通の機能を抽出し、他の派生クラスの基本クラスとして使用される別のクラスを作成するクラスです。インスタンス化は許可されておらず、抽象クラスはabstractキーワードを使用して定義されます。

抽象メソッドにはメソッドの定義のみがあり、メソッド本体はありません。メソッド本体はサブクラスで実装する必要があります。

サンプルコードは次のとおりです。

// abstract キーワードを使用して抽象クラスを定義します。抽象クラスは初期化する必要がなく、基本クラスとしてのみ使用されます。abstract class Department {
  // 名前メンバー、パラメータ属性コンストラクタを初期化します(public name: string) {}

  printName(): void {
    console.log('部門名: ' + this.name)
  }
  // 抽象メソッドには abstract キーワードを含める必要があります abstract printMeeting(): void // 派生クラスで実装する必要があります}

クラス AccountingDepartment は Department を拡張します {
  コンストラクタ() {
    super('Accounting Department') // 派生クラスのコンストラクタで super() を呼び出す必要があります
  }

  printMeeting(): void {
    console.log('経理部門は資金管理を担当しています')
  }
}

// const department = new Department() // 例外がスローされます: 抽象クラスのインスタンスを作成できません // 抽象サブクラスをインスタンス化します const department = new AccountingDepartment()
// 抽象クラス department.printName() のメソッドを呼び出す // 部門名: Accounting Department // 派生クラス department.printMeeting() に実装された抽象メソッドを呼び出す // Accounting Department は、お金の管理を担当する部門です

8. クラスとインターフェース

クラス定義では、クラスのインスタンスの型とコンストラクターの 2 つが作成されます。クラスは型を作成できるため、これは前に学習したインターフェースに似ており、インターフェースが使用される場所でクラスを使用できます。

サンプルコードは次のとおりです。

// クラスを定義する class Point {
    x: 数値
    y: 数値
}
// インターフェースの継承とクラスを定義する interface Point3d extends Point {
    z: 数値
}

point3d: Point3d = { x: 1, y: 2, z: 3 } とします。

クラスは、実装することでインターフェースを実装できます。サンプル コードは次のとおりです。

// インターフェイスEatを定義する{
  食べる(食べ物: 文字列): void
}
インターフェース実行{
  実行(距離: 数値): void
}

// インターフェースを実装するクラスを定義する class Person implements Eat, Run {
  食べる(食べ物: 文字列): void {
    console.log(食べ物)
  }
  実行(距離: 数値) {
    console.log(距離)
  }
}
輸出 {}

TypeScript のクラスに関するこの記事はこれで終わりです。TypeScript のクラスに関するより関連性の高いコンテンツについては、123WORDPRESS.COM の過去の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • TypeScript での関数オーバーロード
  • TypeScript の関数
  • TypeScript 関数の定義と使用例のチュートリアル
  • TypeScriptの一般的な型と応用例の説明
  • TypeScript の関数とクラスを理解していますか?

<<:  フィルターを使用して画像に透明な CSS を書く方法

>>:  HTML における iFrame タグの 2 つの使用法

推薦する

Centos での TCPWrappers アクセス制御の実装

1. TCP ラッパーの概要TCP Wrappers は TCP サービス プログラムを「ラップ」し...

jQueryは広告を上下にスクロールする効果を実現します

この記事では、広告を上下にスクロールする効果を実現するためのjQueryの具体的なコードを参考までに...

Linuxファイル削除後にスペースが解放されない問題の詳しい説明

序文システム領域の使用量が大きすぎて消去する必要がある場合、または特定のファイルを消去する必要がある...

MySQL InnoDB ReplicaSet の簡単な紹介

目次01 InnoDBレプリカセットの紹介02 InnoDBレプリカセットの制限03 導入前に知って...

vue-cropper を使用して vue で写真をトリミングする方法をご存知ですか?

目次1. インストール: 2. 使用方法: 3. 組み込みメソッド: 4. 使用方法:要約する公式サ...

古い Vue プロジェクトに Vite サポートを追加する方法

1. はじめに会社のプロジェクトを引き継いで2年になります。今では毎回プロジェクトを起動するのに1分...

MySQL 8.0.25 のインストールと設定方法のグラフィックチュートリアル

MySQL 8.0.25の最新のダウンロードとインストールのチュートリアルは参考になります。具体的な...

RGBA の「a」は何を意味するのでしょうか? CSS RGBA カラー ガイド

RGBAは色の値と透明度を設定できるCSSカラーです以下は、rgba() を使用して白色を 50% ...

CSS3 で translate と transition を使用する方法

translate と transition は非常に強力で、習得するのは不可能だといつも感じていま...

既存のDockerコンテナの内容を変更する方法

1. Docker psはコンテナをリストします 2. Docker cpはコンテナにファイルをコピ...

MySQLデータベースに画像を保存するいくつかの方法

通常、ユーザーがアップロードした写真はデータベースに保存する必要があります。一般的に、解決策は 2 ...

WeChatアプレットが検索ボックス機能を実装

この記事の例では、WeChatアプレットの検索ボックス機能を実装するための具体的なコードを参考までに...

MySQL でメタデータ ロックがブロックされている場所を確認する方法

MySQL でメタデータ ロックがブロックされている場所を確認する方法手順: 1. セッション1の実...

MySQL 8.0.18 はクローンプラグインを使用して MGR 実装を再構築します

3 ノード MGR 内の 1 つのノードに異常があり、MGR クラスターに再度追加する必要があるとし...

MySQLのジョイントインデックス機能の分析と使用例

この記事では、例を使用して、MySQL 共同インデックスの機能と使用方法を説明します。ご参考までに、...