自学内容网 自学内容网

TypeScript 从入门到进阶之基础篇(九) Class类篇

请添加图片描述

系列文章目录

TypeScript 从入门到进阶系列

  1. TypeScript 从入门到进阶之基础篇(一) ts基础类型篇
  2. TypeScript 从入门到进阶之基础篇(二) ts进阶类型篇
  3. TypeScript 从入门到进阶之基础篇(三) 元组类型篇
  4. TypeScript 从入门到进阶之基础篇(四) symbol类型篇
  5. TypeScript 从入门到进阶之基础篇(五) 枚举类型篇
  6. TypeScript 从入门到进阶之基础篇(六) 类型(断言 、推论、别名)| 联合类型 | 交叉类型 篇
  7. TypeScript 从入门到进阶之基础篇(七)泛型篇
  8. TypeScript 从入门到进阶之基础篇(八)函数篇
    持续更新中…


前言

在JavaScript中class(类)是一种组织代码的方式,它允许我们创建对象和对象的行为。它是一种面向对象编程(OOP)的概念,在ES6中被引入,通过class关键字,可以定义类。使用class关键字可以定义类,通过类可以创建多个实例对象。本章将讲解如何在TypeScript 中使用class(类)。


一、class类的基本使用

定义类的语法与JavaScript类似,使用class关键字来定义一个类。类可以包含属性、方法和构造函数等。

注意:在TypeScript是不允许直接在constructor 定义变量的 需要先在constructor的上面进行声明

例如,下面是一个简单的示例,演示了如何在TypeScript中定义一个类:

class Person {
//先进行声明
  name: string;
  age: number;
//才能在constructor 中使用
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }

  sayHello() {
    console.log(`Hello, my name is ${this.name} and I'm ${this.age} years old.`);
  }
}

let person = new Person("John", 25);
person.sayHello();

在上面的例子中,我们定义了一个名为Person的类,它有两个属性nameage,一个构造函数和一个sayHello方法。构造函数用于创建类的实例,并接受nameage作为参数。

我们可以使用new关键字来创建一个Person对象,并调用sayHello方法来输出欢迎消息。

二、class类中的修饰符

类成员(属性和方法)可以使用以下修饰符来定义其访问权限:

  1. public: 默认修饰符,表示成员在类内部和外部都可以访问。
  2. private: 表示成员只能在类内部访问,外部无法访问。
  3. protected: 表示成员可以在类内部和该类的子类中访问,外部无法访问。
  4. readonly: 表示成员只能在初始化时或构造函数中赋值,并且不能被修改。
  5. static: 表示成员属于类本身,而不是类的实例。可以在类内部和类外部直接访问,无需实例化。

例如,以下代码示例演示了如何使用修饰符:

class Person {
  public name: string; // 公有属性,默认修饰符
  private age: number; // 私有属性
  protected gender: string; // 受保护属性
  readonly id: string; // 只读属性
  static count: number; // 静态属性

  constructor(name: string, age: number, gender: string, id: string) {
    this.name = name;
    this.age = age;
    this.gender = gender;
    this.id = id;
    Person.count++;
  }

  public sayHello() {
    console.log(`Hello, my name is ${this.name}.`);
  }

  private getAge() {
    return this.age;
  }

  protected getGender() {
    return this.gender;
  }

  static getCount() {
    return Person.count;
  }
}

const person = new Person('John', 25, 'male', '1234567890');
console.log(person.name); // 可访问,输出 'John'
// console.log(person.age); // 私有属性,无法访问
// console.log(person.gender); // 受保护属性,无法访问
console.log(person.id); // 只读属性,可访问,输出 '1234567890'
person.sayHello(); // 可调用,输出 'Hello, my name is John.'
// person.getAge(); // 私有方法,无法调用
// person.getGender(); // 受保护方法,无法调用
console.log(Person.count); // 静态属性,可直接访问,输出当前实例数

这是一个使用各种修饰符定义类成员的例子,你可以根据自己的需求选择适当的修饰符来限制成员的访问权限。

三、class类中存取器的使用

存取器(accessor)是一种特殊的属性,用于对类的属性进行读取和写入操作。存取器由get和set关键字定义,分别用于获取和设置属性的值。

下面是一个使用存取器的示例:

class Person {
  private _name: string;

  get name(): string {
    return this._name;
  }

  set name(value: string) {
    this._name = value;
  }
}

let person = new Person();
person.name = "Alice";
console.log(person.name); // Output: Alice

在上面的例子中,Person类具有一个私有属性_name和一个公共的存取器name。存取器name的get方法返回_name的值,set方法设置_name的值。通过使用存取器,我们可以在外部像访问属性一样获取和设置_name的值。

另外,存取器可以有只读的属性。只读属性只有get方法,没有set方法,一旦设置了初始值后就不能再修改。

class Person {
  private readonly _name: string;

  constructor(name: string) {
    this._name = name;
  }

  get name(): string {
    return this._name;
  }
}

let person = new Person("Alice");
console.log(person.name); // Output: Alice
person.name = "Bob"; // Error: Cannot assign to 'name' because it is a read-only property

在上面的例子中,Person类的_name属性是只读的,只能通过构造函数初始化,并且不能修改其值。通过使用只读属性,我们可以限制属性的修改,提高代码的可靠性和安全性。

四、用接口定义类

可以使用接口来定义类。可以在接口中定义类的属性和方法,并且类需要遵循接口的定义。

下面是一个示例:

interface Animal {
  name: string;
  age: number;
  sound(): void;
}

class Dog implements Animal {
  name: string;
  age: number;

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }

  sound(): void {
    console.log("Woof!");
  }
}

let myDog: Animal = new Dog("Max", 5);
myDog.sound(); // 输出 "Woof!"

在上面的例子中,定义了一个Animal接口,它包含了name、age和sound方法。然后创建了一个Dog类,它实现了Animal接口。最后,创建了一个myDog对象,它是一个Animal类型的变量,可以调用sound方法。

通过使用接口来定义类,可以使代码更加清晰和易于维护,同时也可以提供更好的类型检查和类型推断。

五、类的继承

类之间可以通过继承来建立父子关系。一个类可以继承另一个类的属性和方法,并且可以添加自己的属性和方法。类的继承使用 extends
关键字。

下面是一个示例,展示了一个父类 Animal 和一个子类 Cat 的继承关系:

class Animal {
  name: string;

  constructor(name: string) {
    this.name = name;
  }

  makeSound() {
    console.log('Animal is making a sound.');
  }
}

class Cat extends Animal {
  meow() {
    console.log('Cat is meowing.');
  }
}

const myCat = new Cat('Tom');
console.log(myCat.name); // 输出 "Tom"
myCat.makeSound(); // 输出 "Animal is making a sound."
myCat.meow(); // 输出 "Cat is meowing."

在上面的例子中,Cat 类继承了 Animal 类,因此它拥有了 name 属性和 makeSound() 方法。同时,它还添加了自己的方法 meow()

注意,当子类继承父类时,子类的构造函数中必须调用 super() 方法,以调用父类的构造函数,并传递必要的参数。在上面的例子中,Cat 类的构造函数调用了 super(name),以调用 Animal 类的构造函数。

此外,子类还可以重写父类的方法。在子类中,可以使用 super 关键字来调用父类的方法。例如,在上面的例子中,Cat 类的 makeSound() 方法重写了父类的方法,但在方法体内部通过 super.makeSound() 来调用父类的方法。

六、抽象类的使用

可以使用抽象类来定义一个抽象的基类,它不能被直接实例化,只能被继承。抽象类可以包含抽象方法和非抽象方法。

下面是一个使用抽象类的示例:

abstract class Animal {
  protected name: string;

  constructor(name: string) {
    this.name = name;
  }

  abstract makeSound(): void;

  move(distance: number): void {
    console.log(`${this.name} moved ${distance} meters.`);
  }
}

class Cat extends Animal {
  makeSound(): void {
    console.log(`${this.name} makes sound: Meow!`);
  }
}

let myCat: Cat = new Cat("Tom");
myCat.makeSound(); // 输出 "Tom makes sound: Meow!"
myCat.move(10); // 输出 "Tom moved 10 meters."

在上述代码中,Animal 类是一个抽象类,它有一个抽象方法 makeSound 和一个非抽象方法 moveCat 类继承自 Animal 类,并实现了 makeSound 方法。我们创建一个 Cat 类的实例 myCat,并调用它的方法和非抽象方法。


总结

总结起来,使用 TypeScript类可以方便地定义和组织代码,提供了面向对象编程的特性,如封装、继承和多态。同时,通过类型检查,可以减少一些常见的错误,并提供更好的代码智能提示。


原文地址:https://blog.csdn.net/weixin_49014702/article/details/135461797

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!