ts のクラスは、一部の型チェックと機能拡張を除いて、js のクラスと似ています。
基本的な使い方
キーワードを使用してclass
クラスを宣言し、いくつかのインスタンスのプロパティとメソッドを宣言します。
class Dog {
//定义几个实例属性
name: string = '小狗'
age: number = 5
//定义一个实例方法,该方法会绑定在类的原型对象上
sayHi() {
console.log('Hi')
}
}
let dog = new Dog() //Dog: {"name": "小狗","age": 5}
dog.sayHi() //hi
プロパティ値を手動で設定する
上記のコードでは、インスタンスの属性がハードコーディングされており、あまり実用的ではないため、constructor
手動で割り当て操作を実行しようとしています。
class Dog {
name: string
age: number
constructor(name: string, age: number) {
this.age = age
this.name = name
}
sayHi() {
console.log('Hi')
}
}
let dog = new Dog('富贵', 5)
console.log(dog) //Dog: {"name": "小狗","age": 5}
dog.sayHi() //hi
静的プロパティを設定する
いくつかの静的プロパティとメソッドをクラスに設定することもできます。これらのプロパティ メソッドはインスタンスを介して渡す必要はなく、クラスを介して直接使用できます。
class Dog {
static gender: string = '雌'
static getGender() {
console.log('我的性别是' + Dog.gender)
}
}
console.log(Dog.gender) // '雌'
Dog.getGender() // '我的性别是雌'
継承する
クラスに関して言えば、継承について話さなければなりません。多くの場合、継承により一部のパブリック メソッドまたはプロパティを抽象化およびカプセル化できるため、コードの再利用が削減されます。
class Animal {
type: string
gender: boolean
constructor(type: string, gender: boolean) {
this.type = type
this.gender = gender
}
}
class Dog extends Animal {
age: number
constructor(gender: boolean, age: number) {
super('dog', gender)
this.age = age
}
}
let dog: Dog = new Dog(true, 5)
console.log(dog)
// {
// "type": "dog",
// "gender": true,
// "age": 5
// }
継承プロセス中に、一部のプロパティまたはメソッドをオーバーライドする場合があります。
class Animal {
type: string
gender: boolean
constructor(type: string, gender: boolean) {
this.type = type
this.gender = gender
}
sayHi() {
console.log('动物再叫')
}
}
class Dog extends Animal {
age: number
constructor(gender: boolean, age: number) {
super('dog', gender)
this.age = age
}
sayHi() {
console.log('小狗在叫')
}
}
let dog: Dog = new Dog(true, 5)
dog.sayHi() //小狗在叫
修飾子
public (デフォルト修飾子)
通常クラスを定義すると、内部のプロパティやメソッドはデフォルトでpublicになります。つまり、デフォルトで定義されているメソッドとプロパティはパブリックであり、クラスの内外で使用できます。
class Dog {
name: string = '小狗'
age: number = 5
sayHi() {
console.log(this.name'说Hi') //直接在类的内部使用name属性
}
}
let dog = new Dog() //Dog: {"name": "小狗","age": 5}
dog.name // 直接在类的外部使用name属性
private (プライベート)
メンバーがプライベートとしてマークされている場合、そのメンバーが宣言されているクラスの外部からはアクセスできません。
class Dog {
private name: string = '小狗'
sayHi() {
console.log(this.name + '说Hi') //直接在类的内部使用name属性
}
}
let dog = new Dog() //Dog: {"name": "小狗","age": 5}
dog.sayHi() // 小狗说Hi
dog.name // Property 'name' is private and only accessible within class 'Dog'.
継承されたクラスにもアクセスできません。
class Animal {
private type: string
gender: boolean
constructor(type: string, gender: boolean) {
this.type = type
this.gender = gender
}
}
class Dog extends Animal {
age: number
constructor(gender: boolean, age: number) {
super('dog', gender)
this.age = age
console.log(this.type) //Property 'type' is private and only accessible within class 'Animal'.
}
}
protected (class private)
protected
はそれに似ていますprivate
が、それが定義するプロパティとメソッドには継承されたクラスでアクセスできます。
class Animal {
protected type: string
gender: boolean
constructor(type: string, gender: boolean) {
this.type = type
this.gender = gender
}
}
class Dog extends Animal {
age: number
constructor(gender: boolean, age: number) {
super('dog', gender)
this.age = age
console.log(this.type) //dog
}
}
readonly (読み取り専用)
読み取り専用の実装はクラス属性で定義するか、クラス属性constructor
に割り当てる必要があります。
パラメータのプロパティ
上記のクラスでは、コンストラクターでプロパティを宣言するたびにconstructor
、内部で代入操作を実行する前に、最初に外部で型を宣言し、次にコンストラクターで仮パラメーターを宣言する必要があることがわかりましたが、完全に使用できます。パラメータ属性宣言タイプ宣言ステップ。
class Animal {
constructor(protected type: string, public gender: boolean) {
this.type = type
this.gender = gender
}
}
コンストラクター上で修飾子を直接使用することで、型宣言のステップを省略し、コンストラクター内で直接代入操作を実行します。
get/Set (アクセサー)
class Person {
constructor(public name: string, public age: number) {
this.name = name
this.age = age
}
}
let user: Person = new Person('fufu', 20)
user.age = 1000
上記のコードでは Person クラスを定義していますが、このクラスには age 属性があり、インスタンスを生成した後、任意に年齢を変更したり、10,000 に変更したりすることもできます。これは明らかに不合理です。get/set を使用してプロパティにアクセスし、設定できます。
class Person {
constructor(public name: string, private _age: number) {
this.name = name
this._age = _age
}
get getAge() {
return this._age
}
set setAge(num: number) {
if (num > 120) {
console.log('数字太大啦!')
}
}
}
let user: Person = new Person('fufu', 20)
user.setAge = 130 //数字太大啦!
console.log(user.getAge) // 20
抽象クラス
多くの場合、インスタンスの作成にすべてのクラスを使用したくないことがあります。たとえば、動物クラスがある場合、それを他のクラスに継承させるだけでよく、誰もそれを直接使用してインスタンスを作成したくありません。この場合、抽象化を使用する必要があります。
abstract class Animal {
constructor(public breed: string) {
this.breed = breed
}
}
class Dog extends Animal {
constructor() {
super('dog')
}
}
let animal: Animal = new Animal('dog') //Cannot create an instance of an abstract class.
let dog: Dog = new Dog()
console.log(dog.type) // 'dog'
抽象メソッドは抽象クラスで定義することもできます。抽象メソッドには具体的な実装が含まれていないため、派生クラスで実装する必要があります。抽象メソッドの構文はインターフェイス メソッドと似ています。どちらもメソッド シグネチャを定義しますが、メソッド本体は含まれません。
abstract class Animal {
constructor(protected breed: string) {
this.breed = breed
}
abstract sayHi(): void
}
class Dog extends Animal {
constructor() {
super('dog')
}
sayHi() {
console.log(this.breed + '在叫!')
}
}
let dog: Dog = new Dog()
dog.sayHi() // dog在叫!
プロパティを定義するときは、初期値を割り当てるか、コンストラクターで値を割り当てる必要があることに注意してください。! または ? を使用して、それがオプションであることを表明または示すことができます。
class Dog {
name?: string
age!: number
}