TypeScript 基础-面向对象(第四章)

1. 类

1.1. 定义类

1
2
3
4
5
6
7
8
9
10
11
12
class 类名 {
属性名: 类型;

constructor(参数: 类型){
this.属性名 = 参数;
}

方法名(){
....
}

}

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Person{
name: string;
age: number;
static gander: male; // static 静态属性
readonly type: gad; // readonly,只读属性,无法修改

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

sayHello(){ // 静态函数加 static
console.log(`大家好,我是${this.name}`);
}
}

1.2. 使用类

1
2
3
const p = new Person('孙悟空', 18);
p.sayHello();
Person.gander;

2. 封装

  • 只能在属性前使用,TS 中属性具有以下修饰符:
    • public(默认值):可以在类、子类和对象中修改
    • protected:可以在类、子类中修改
    • private:可以在类内部中修改
    • readonly:只可以读取不可修改
  • 可以使用 getset 方法的语法糖来时限属性存取
    • get name() { return this.name }
    • set name(value: string) { this.name = value }
  • 可以在构造方法中使用修饰符的语法糖来完成属性的定义
    1
    2
    3
    constructor(public name: string, public age: number) {

    }

3. 继承

  • 与 java 中一样,使用关键字 extends 来继承,使用 super 应用父类,可以重写父类方法
  • 子类中使用构造函数,必须显示调用父类构造函数

4. 多态

  • 与 java 中一样,可以使用父类类型来创建子类

5. 抽象类

与 java 中一样,使用关键字 abstract 来表示抽象,可以是类、方法,抽象方法必须定义在抽象类中,继承后也必须实现

6. 接口

  • 与 java 中一样,使用关键字 interface 来表示接口,使用 implements 实现接口
  • 接口名可以重复,实现时意味着需要实现全部同名接口

7. 泛型

7.1. 泛型函数

与 java 中一样,当函数有一个参数类型不确定时,可以使用泛型:

1
2
3
4
5
6
7
function test<T>(arg: T): T{
return arg;
}
// 限定范围,MyInteger 的子类
function test<T extends MyInteger>(arg: T): number{
return arg.length;
}

泛型函数使用方法:

1
2
3
4
// 直接使用,利用类型推断确定
test(10);
// 指定类型
test<number>(10)

7.2. 泛型类

与 java 中一样,可以在类中使用

1
2
3
4
5
6
7
class MyClass<T>{
prop: T;

constructor(prop: T){
this.prop = prop;
}
}

7.2. 泛型约束

有些时候,无法确定泛型类中具有某个属性时,可以使用接口的方式来定义之,可以保证编译器不会报错

1
2
3
4
5
6
7
8
interface Lengthwise {
length: number;
}

function loggingIdentity<T extends Lengthwise>(arg: T): T {
console.log(arg.length); // Now we know it has a .length property, so no more error
return arg;
}

8. 函数

  • 需要给函数参数和返回值添加类型:
    1
    2
    3
    function add(x: number, y: number): number {
    return x + y;
    }
  • 在函数参数声明时,可以使用=?来对参数进行赋默认值或者可选
    1
    2
    3
    function buildName(firstName?: string, lastName: string = "Smith") {
    // ...
    }
  • 在函数参数声明时,可以使用...来传递多个参数
    1
    2
    3
    4
    5
    function buildName(firstName: string, ...restOfName: string[]) {
    return firstName + " " + restOfName.join(" ");
    }
    // 可以传递多个参数
    let employeeName = buildName("Joseph", "Samuel", "Lucas", "MacKinzie");
  • 函数名相同,但参数类型或者参数数量不一致的情况,叫做函数重载,可以在编译时校验非法参数
    1
    2
    3
    function(x:string, y:string): string;
    function(x:number, y:number): number;
    ...