TS类
在TS中声明了一个类的时候,实际上声明了两个东西
一个是创建了 类的实例的类型
一个是创建了 一个叫构造函数的值
这个 构造函数 会在创建类实例的时候被调用
如何定义类
存取器 构造函数
class User {
    private myName:string;
    constructor(myName: string) { // 构造函数,初始化成员属性
        this.myName = myName;
    }
    get name() { // 存取器,用于修改类中属性,
        return this.myName;
    }
    set name(value) {
        this.myName = value;
    }
}
// 存取器只有get 没有set 的private属性,会被自动推断为readonly
类 编译结果
static挂载在函数对象上
get/set挂载在原型对象上
public/private/protected 挂载在实例对象上
get/set 属性 不可和 public/private/protected 重名,可以和 static 重名
get/set 属性 编译的target 必须是 ES5及以上
class Animal1 {
    static type = "1";
    public type2 = "1"
    private type3 = "1";
    protected type4 = "1";
    get type5() {
        return "1"
    }
}
const a = new Animal1()
var Animal1 = /** @class */ (function () {
    function Animal1() {
        this.type2 = "1";
        this.type3 = "1";
        this.type4 = "1";
    }
    Object.defineProperty(Animal1.prototype, "type5", {
        get: function () {
            return "1";
        },
        enumerable: false,
        configurable: true
    });
    Animal1.type = "1";
    return Animal1;
}());
修饰符
public: 默认,可以在任何地方使用
private: 不可为声明的类的外部访问
protected: 在自己和子类中可以访问,其他地方不可以访问
省略属性的声明
实例上的属性需要先声明在使用
在 构造函数 参数 前添加修饰符,可省略属性的声明
class User2 {
    constructor(public myName: string) {}
    get name() {
        return this.myName;
    }
    set name(value) {
        this.myName = value;
    }
}
let user = new User2('lzy');
console.log(user.name);
readonly
readonly 修饰的变量 只能在构造函数中初始化
readonly 在编译时被检查 const 在运行时被检查
兼容性
在TS中,
正常情况 Animal类 的变量 可接收 Employee类型的数据,
因为他们类型检查一样(二者都有且仅有name,且假设二者的name是public)
但是,比较类型的时候, 如果出现了 private/protected成员,
则同时需满足 另一个类也存在这样一个private成员, 且来自于同一处.
public修饰的成员则不要求来自同一处
class Animal {
    private name: string;
    constructor(theName: string) { this.name = theName; }
}
class Rhino extends Animal {
    constructor() { super("Rhino"); }
}
class Employee {
    private name: string;
    constructor(theName: string) { this.name = theName; }
}
let animal = new Animal("Goat");
let rhino = new Rhino();
let employee = new Employee("Bob");
animal = rhino;
animal = employee; // 错误: Animal 与 Employee 不兼容.
//  尽管Employee里也有一个私有成员name,但它明显不是Animal里面定义的那个
继承
子类 构造函数 必须使用 super() 以执行父类的构造函数
class Person {
    name: string;//定义实例的属性,默认省略public修饰符
    age: number;
    constructor(name:string,age:number) {//构造函数
        this.name=name;
        this.age=age;
    }
    getName():string {
        return this.name;
    }
    setName(name:string): void{
        this.name=name;
    }
}
class Student extends Person{
    no: number;
    constructor(name:string,age:number,no:number) {
        super(name,age);
        this.no=no;
    }
    getNo():number {
        return this.no;
    }
}
let s1=new Student('lzy',25,1);
console.log(s1);
静态属性和静态方法
静态属性 一般代表所有实例会共同用到的 属性
可通过 类.静态 类的实例.静态 访问
不需要 创建类实例可直接获取
class Father {
    static className='Father';
    static getClassName() {
        return Father.className;
    }
    public name: string;
    constructor(name:string) {//构造函数
        this.name=name;
    }
}
console.log(Father.className);
console.log(Father.getClassName());
抽象类
作为其他派生类的基类使用,代表一种抽象的概念.
无法被实例化,只能被继承.
抽象类中的抽象方法,不能在抽象类中实现,
只能在派生类中实现,且必须在派生类中实现.
一般不会被直接实例化.
抽象方法 和 接口方法 都定义方法前面 当不包含方法体.
不同于接口,抽象类可以包含成员的实现细节.
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(); // 错误: 方法在声明的抽象类中不存在
类装饰器
装饰器是一种特殊类型的声明,
它能够被附加到类声明、方法、属性或参数上,可以修改类的行为
常见的装饰器有 类装饰器 属性装饰器 方法装饰器 参数装饰器
装饰器的写法分为普通装饰器和装饰器工厂