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

推薦する

MySQL で UTF-8 エンコーディングを使用しないのはなぜですか?

MySQL UTF-8 エンコーディングMySQL は 2003 年のバージョン 4.1 から U...

Vueプロジェクトの最適化とパッケージ化の詳細な説明

目次序文1. ルーティングの遅延読み込み1. ルートの遅延読み込みが必要なのはなぜですか? 2. ル...

MySQL/MariaDB ルートパスワードリセットチュートリアル

序文パスワードを忘れることは、よく遭遇する問題です。MySQL または MariaDB データベース...

Tomcat を使用して Centos 環境に SpringBoot WAR パッケージをデプロイする

戦争パッケージを準備する1. 既存のSpringBootプロジェクトを準備し、pomに依存関係を追加...

MySQL 最適化 query_cache_limit パラメータの説明

クエリキャッシュ制限query_cache_limit は、単一のクエリで使用できるバッファ サイズ...

Mac OS10.12 に mysql5.7.18 をインストールするチュートリアル

ウェブ全体を検索して、さまざまな落とし穴を見つけましたが、問題は解決しませんでした。ついに自分でも分...

Linux CentOS MySQL データベースのインストールと設定のチュートリアル

MySQLデータベースのインストールに関するメモ、みんなで共有a) MySQL ソースインストールパ...

メタビューポートタグ(モバイルブラウジングズームコントロール)の使用方法

OP が現在のファームウェアで Web ページを開くと、常に 50% にズームアウトされてから表示さ...

CentOS 7 は Hadoop 2.10 の高可用性 (HA) をビルドします

この記事では、CentOS 7 で高可用性 Hadoop 2.10 クラスターを構築する方法を紹介し...

Vue ベースの要素ボタン権限実装ソリューション

背景要件: ERP システムに「ボタン権限制御」機能を追加する必要があり、権限の制御粒度をボタン レ...

MySQL シリーズ 9 MySQL クエリ キャッシュとインデックス

目次チュートリアルシリーズ1. MySQL アーキテクチャクエリキャッシュキャッシュされないクエリ:...

虫眼鏡効果を実現するJavaScript

この記事では、虫眼鏡効果を実現するためのJavaScriptの具体的なコードを参考までに紹介します。...

nodejs で worker_threads を使用して新しいスレッドを作成する方法

導入前の記事で述べたように、NodeJS には 2 種類のスレッドがあります。1 つは、ユーザー リ...

Linux 上の MariaDB は root ユーザーで起動します (推奨)

最近、セキュリティ製品をテストする必要があったため、mariadb の起動ユーザーを root に調...

HTML テーブルタグについての簡単な説明

主にその構造といくつかの重要な特性について説明します。少しずつ改善しながら紹介していきます。 1) ...