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 つの使用法

推薦する

ドロップダウンメニュー効果を実現するJavaScript

参考までに、JavaScriptを使用してドロップダウンメニューを実装します。具体的な内容は次のとお...

MySQL にテキストと画像を保存する方法

Oracle の大きなテキスト データ型 Clob 長いテキスト型 (MySQL ではサポートされて...

echartsマップカルーセルハイライトを解決するための記事

目次序文やることリストやるだけ地図を準備するインスタンスをバックアップ用に保存するタイマーカルーセル...

JavaScript の async と await のシンプルで詳細な学習

目次1. はじめに2. 詳しい説明2.1、非同期2.1.1. 関数はPromise以外のオブジェクト...

HTML、CSS、JSコメントの標準的な使用法の概要

必要なコメントを追加することは、責任感と道徳心のあるフロントエンド開発者が持つべき良い習慣であり、コ...

JavaScript配列についてさらに詳しく知るのに役立つ記事

目次1. 配列の役割: 2. 配列の定義: 1. コンストラクタを通じて配列を作成する2. リテラル...

CentOS での Docker の詳細なインストール チュートリアル

DockerにはCEとEEがあり、CE版はコミュニティ版(無料)、EE版はセキュリティを重視したエン...

Vue3 プロジェクトで WeChat 認証ログインをエレガントに実装する方法

目次序文準備する実装のアイデアコードについて要約する序文WeChat 認証ログインは、WeChat ...

Mysqlがデータベースに接続するときのホストとユーザーのマッチングルールについての簡単な説明

--データベースに接続するとき、ホストとユーザーのマッチングルール公式ドキュメント: https:/...

CSS を使用して物流の進行状況のスタイルを実装するためのサンプルコード

効果: CSS スタイル: <スタイル タイプ="text/css">...

Vue スクロールダウンしてさらにデータを読み込む スクロールケースの詳細な説明

vue-無限スクロールインストール npm インストール vue-infinite-scroll -...

強くお勧めします! Vue 3.2 でシンタックスシュガーを設定する

目次前の1. セットアップ構文シュガーとは何か2. セットアップコンポーネントを使用して自動的に登録...

VueはOpenLayersを使用してTiandi MapとAmapを読み込み

目次1. 世界地図1. VueにOpenLayersをインストールする2. アマップ1. 世界地図1...

テンプレートタグの使用方法の詳細な説明(Vue での使用方法の概要を含む)

目次1. HTML5のテンプレートタグ2. テンプレートタグ操作のプロパティとメソッド3. Vueの...

JS WebSocketを使用して簡単なチャットを実装する方法

目次ショートポーリングロングポーリングウェブソケットコミュニケーションの原則シンプルな1対1チャット...