TS系列篇|类(class) 您所在的位置:网站首页 类class定义 TS系列篇|类(class)

TS系列篇|类(class)

#TS系列篇|类(class) | 来源: 网络整理| 查看: 265

"不畏惧,不将就,未来的日子好好努力"——大家好!我是小芝麻😄

类(Class)定义了一件事物的抽象特点,包含它的属性和方法

1、定义类

在 TypeScript 中,我们也是通过 Class 关键字来定义一个类, 使用 constructor 定义构造函数。

构造函数: constructor

主要用于初始化类的成员变量属性 类的对象创建时自动调用执行 没有返回值 class Animal { public name: string; constructor(name: string) { this.name = name; } sayHi(): string { return `My name is ${this.name}`; } } 2、类的继承

使用 extends 关键字实现继承,子类中使用 super 关键字来调用父类的构造函数和方法。

子类继承父类后子类的实例就拥有了父类中的属性和方法,可以增强代码的可复用性 将子类共用的方法抽象出来放在父类中,自己特殊逻辑放在子类中重写父类的逻辑 super 可以调用父类上的方法和属性: (相当于ES5的:在静态方法和构造函数中指向父类; 在普通函数中指向父类的prototype;) class Animal { public name: string; constructor(name: string) { this.name = name; } sayHi(): string { return `My name is ${this.name}`; } } class Cat extends Animal { constructor(name) { super(name); // 调用父类的 constructor(name) console.log(this.name); } sayHi(): string { // 将子类共用的方法抽象出来放在父类中,自己特殊逻辑放在子类中重写父类的逻辑 return 'Meow, ' + super.sayHi(); // 调用父类的 sayHi() } } let c = new Cat('Tom'); // Tom console.log(c.sayHi()); // Meow, My name is Tom 2.1 重写(override) VS 重载(overload) 重写是指子类重写继承自父类的方法 重载是指为同一个函数提供多个类型定义 2.2 继承 VS 多态 继承(inheritance)子类继承父类,子类除了拥有父类的所有特性外,还有一些具体的特性 多态(Polymorphism)由继承而产生了相关的不同的类,对同一个方法可以有不同的行为 3、类的修饰符

TypeScript 中有三类访问修饰符,分别是: public、private、protected。不写默认为 public

public :自己、自己的子类 和其他类都可以访问 (默认值) protected 受保护的 自己和自己的子类能访问, 其他类不能访问 private 私有的 只能自己访问,自己的子类不能访问,其他类更不能访问 class Father { public name: string protected age: number private money: number constructor(name: string, age: number, money: number) { this.name = name this.age = age this.money = money } getName(): string { return this.name } setName(name: string): void { this.name = name } } class child extends Father { constructor(name: string, age: number, money: number) { super(name, age, money) } desc() { console.log(`${this.name}${this.age}${this.money}`) // 属性“money”为私有属性,只能在类“Father”中访问 } } let children = new child('金色小芝麻', 18, 1000) console.log(children.name) console.log(children.age) // ERROR 属性“age”受保护,只能在类“Father”及其子类中访问。 console.log(children.money) // ERROR 属性“money”为私有属性,只能在类“Father”中访问。 当构造函数修饰为 private 时,该类不允许被继承或者实例化: class Animal { public name: string; private constructor(name: string) { this.name = name; } } class Cat extends Animal { // 无法扩展类“Animal”。类构造函数标记为私有。 constructor(name: string) { super(name); } } let a = new Animal('Jack'); // 类“Animal”的构造函数是私有的,仅可在类声明中访问。 当构造函数修饰为 protected 时,该类只允许被继承: class Animal { public name: string; protected constructor(name: string) { this.name = name; } } class Cat extends Animal { constructor(name: string) { super(name); } } let a = new Animal('Jack'); // 类“Animal”的构造函数是受保护的,仅可在类声明中访问。 4、readonly

readonly 修饰的变量只能在属性声明时或 构造函数 中初始化

class Animal { // 如果只读修饰符和可见性修饰符同时出现,需要将只读修饰符写在可见修饰符后面。 public readonly name: string constructor(name: string) { this.name = name } changeName(name: string) { this.name = name // ERROR 无法分配到 "name" ,因为它是只读属性。 } } let a = new Animal('hello') a.name = '111' // ERROR 无法分配到 "name" ,因为它是只读属性 a.changeName('nihao') // ERROR 无法分配到 "name" ,因为它是只读属性 console.log(a)

readonly 只是在 编译阶段进行代码检查。运行时依然能打印

编译时: image.png 运行时: image.png 5、参数属性

在上面的例子中,都是在类的定义的顶部初始化实例属性,在 constructor 里接收参数然后对实例属性进行赋值,参数属性就是为了简化这一过程的

直接在 constructor 构造函数的参数前面加上修饰符或readonly => 等同于在类中定义该属性同时给该属性赋值,使代码更简洁。

class User { constructor(public name: string) {} } let user = new User('hello') console.log(user.name) // hello user.name = 'nihao' console.log(user.name) // nihao 6、存取器 在 TypeScript 中,我们可以通过 getter/ setter来改变一个类中属性的读取和赋值行为 class Person { name: string constructor(name: string) { this.name = name } get getName() { // 读取 return this.name } set setName(val: string) { // 赋值 this.name = val.toUpperCase() } } let p1 = new Person('nihao') console.log(p1.getName) p1.setName = 'hello' console.log(p1.name) 7、静态属性和静态方法static

使用 static 修饰符修饰的方法称为静态方法,它们不需要实例化,而是直接通过类来调用:

class Father { public name: string constructor(name: string) { this.name = name } public static className: string = 'Father' static getClassName(): string { return Father.className } } console.log(Father.className) console.log(Father.getClassName()) 8、抽象类和抽象方法abstract

使用 abstract 关键字来定义抽象类和在抽象类内部定义抽象方法。

8.1 抽象类 抽象描述一种抽象的概念,做为其它类的基类使用 无法创建抽象类的实例,抽象类只能被继承 abstract class Animal { name!: string abstract speak(): void } class Cat extends Animal { speak() { console.log('喵喵喵') } } let animal = new Animal(); // ERROR 无法创建抽象类的实例 let cat = new Cat() cat.speak() // 喵喵喵 8.2 抽象方法 抽象方法不能在抽象类中实现,只能在抽象类的具体子类中实现,而且必须实现 抽象方法只能出现在抽象类中 abstract class Animal { name: string abstract speak(): void = ()=>{} // ERROR 方法“speak”不能具有实现,因为它标记为抽象。 } class Cat extends Animal { speak() { // 在这里实现 speak 方法 console.log('喵喵喵') } } 子类可以对抽象类进行不同的实现 abstract class Animal { abstract speak(): void } class Dog extends Animal { speak() { console.log('汪汪汪') } } class Cat extends Animal { speak() { console.log('喵喵喵') } } 8.3 抽象类 VS 接口 不同类之间公有的属性或方法,可以抽象成一个接口(interfaces), 而抽象类是供其他类继承的基类 抽象类本质是一个无法被实例化的类,可以包含成员的实现细节,而接口仅能够用于描述,既不能提供方法的实现细节,也不为属性进行初始化 一个类可以继承一个类或抽象类,但可以实现(implements)多个接口 抽象类也可以实现接口 abstract class Animal { name: string; constructor(name: string) { this.name = name; } abstract speak(): void; } interface Flying { fly(): void } interface age { age: number } class Dog extends Animal implements Flying, age { age: 18 speak() { console.log('汪汪汪') } fly() { console.log('我会飞') } } 访问控制修饰符private、protected、public只读属性readonly静态属性static抽象类、抽象方法abstract 参考文献

[1]. TypeScript中文网

[2]. TypeScript 入门教程



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有