TypeScript 类(class)

419 阅读2分钟

  • 和很多其他语言一样,TypeScript也可以使用类

    class Person {
        public name: string = 'paul';
        getName() {
            return this.name;
        }
    }
    // 创建类的实例
    const person = new Person();
    console.info(person.getName())
    

类的访问权限

  • 默认是public 在类的内部和外部都能访问(也就是说实例对象)

  • private 允许在类内部被使用

  • protected 允许在类内部以及在继承的子类中使用

类的继承

  • 类的简单继承

    class Teacher extends Person {
        getTeacher = ():string => {
            return 'teacher';
        }
        // super是Person的原型属性,所以只能访问到父类的方法但是无法访问super.name
        getName(): string {
            return super.getName() + 'paul';
        }
        getName2 = (): string => {
            return '12';
        }
    }
    
    const teacher = new Teacher();
    console.log(teacher.getTeacher());
    console.log(teacher.getName());
    
    // 这两种类型赋值都是可以的
    let teacher2:Person = new Teacher();
    let teacher3:Teacher = new Teacher();
    
  • constructor写法

    class Person {
        name: string;
        constructor(name: string) {
            this.name = name;
        }
    }
    // 跟上面的写法一致
    class Person {
        constructor(public name: string) {}
    }
    // 子类的构造方法调用父亲
    class Teacher extends Person {
        constructor(public age: number) {
            super('1');
        }
    }
    
    const teacher = new Teacher(1);
    console.info(teacher.name);
    
  • getter setter保护属性

    class Person {
        // name是私有的 只能在内部被访问
        constructor(private _name: string) {}
        get name() {
            return this._name + 'chris';
        }
        set name(name: string) {
            this._name = name;
        }
    }
    
    const person = new Person('paul');
    console.log(person.name);
    person.name = 'haha';
    
  • 静态属性

    // 单例模式
    class Person {
        private static instance: Person;
        // 不允许创建实例了
        private constructor(public name: string) {};
    
        static getInstance() {
            if(!this.instance) {
                this.instance = new Person('paul');
            }
            return this.instance;
        }
    }
    
    const person = Person.getInstance();
    console.info(person.name);
    

抽象类

  • 抽象类的abstract方法必须是public和protected,但是其他方法可以是private

  • 抽象类不能被实例化,只能继承,派生类必须实现抽象方法

  • 不同于接口主要用来制定各种规范,抽象类更多的是实现业务上的严谨性

abstract class Department {

    constructor(public name: string) {
    }

    printName(): void {
        console.log('Department name: ' + this.name);
    }

    abstract printMeeting(): void; // 必须在派生类中实现
}

class AccountingDepartment extends Department {

    constructor() {
        super('Accounting and Auditing'); // 在派生类的构造函数中必须调用 super()
    }

    printMeeting(): void {
        console.log('The Accounting Department meets each Monday at 10am.');
    }

    generateReports(): void {
        console.log('Generating accounting reports...');
    }
}
let department: Department; // 允许创建一个对抽象类型的引用
// department = new Department(); // 错误: 不能创建一个抽象类的实例
department = new AccountingDepartment(); // 允许对一个抽象子类进行实例化和赋值
department.printName();
department.printMeeting();
department.generateReports(); // 错误: 方法在声明的抽象类中不存在

泛型

  • 泛型的简单使用

    class Person<T> {
        constructor(private users: T []) {}
        getItem(index: number) {
            return this.users[index];
        }
    }
    
  • 泛型的extends

    interface Item {
        name: string
    }
    // T必须拥有name属性
    class Person<T extends Item> {
        constructor(private users: T []) {}
        getItem(index: number) {
            return this.users[index].name;
        }
    }
    // 类型推断, T是{ name: 'paul'}
    const data = new Person([
        {
            name: 'paul'
        }
    ]);
    
    // T要么是string 要么是number
    class Person<T extends number | string> {
        constructor(private users: T []) {}
        getItem(index: number) {
            return this.users[index];
        }
    }