详情可见
1.TypeScript类的基本使用

class Person {
    name:string; // 和ES6区别, 需要先定义实例属性, 才能够使用实例属性
    age:number;
    constructor(name:string, age:number){
        this.name = name;
        this.age = age;
    }
    say():void{
        console.log(`我的名称叫${this.name}, 我的年龄是${this.age}`);
    }
    static food:string; // 静态属性
    static eat():void{ // 静态方法
        console.log(`我正在吃${this.food}`);
    }
}
let p = new Person('lnj', 34);
p.say();
Person.food = '蛋挞';
Person.eat();

class Student extends Person{
    book:string;
    constructor(name:string, age:number, book:string){
        super(name, age);
        this.book = book;
    }
    say():void{
        console.log(`我是重写之后的say-${this.name}${this.age}${this.book}`);
    }
    static eat():void{
        console.log(`我是重写之后的eat-${this.food}`);
    }
}
let stu = new Student('zs', 18, '从零玩转');
stu.say();
Student.food = '冰淇淋';
Student.eat();

2.类属性修饰符

public(公开的)      :
如果使用public来修饰属性, 那么表示这个属性是公开的
可以在类的内部使用, 也可以在子类中使用, 也可以在外部使用

protected(受保护的) :
如果使用protected来修饰属性, 那么表示这个属性是受保护的
可以在类的内部使用, 也可以在子类中使用

private(私有的)     :
如果使用private来修饰属性, 那么表示这个属性是私有的
可以在类的内部使用

readonly(只读的)    :

class Person {
    public name:string; // 默认情况下就是public的
    protected age:number;
    private gender:string;
    constructor(name:string, age:number, gender:string){
        this.name = name;
        this.age = age;
        this.gender = gender;
    }
    say():void{
        console.log(`name=${this.name},age=${this.age},gender=${this.gender}`);
    }
}
class Student extends Person{
    constructor(name:string, age:number, gender:string){
       super(name,age,gender);
    }
    say():void{
        // console.log(`name=${this.name}`);
        // console.log(`age=${this.age}`);
        // console.log(`gender=${this.gender}`);
    }
}
let p = new Person('lnj',34, 'male');
p.say();
// console.log(p.age);
// console.log(p.gender);

let stu = new Student('zs', 18, 'female');
stu.say();
// console.log(stu.age);

class Demo {
    readonly name:string;
    constructor(name:string){
        this.name = name;
    }
    static food:string;
}
let demo = new Demo('123');
console.log(demo.name);
// demo.name = 'abc';
console.log(demo.name);

3.类方法修饰符

public :
如果使用public来修饰方法, 那么表示这个方法是公开的
可以在类的内部使用, 也可以在子类中使用, 也可以在外部使用

protected :
如果使用protected来修饰方法, 那么表示这个方法是受保护的
可以在类的内部使用, 也可以在子类中使用

private
如果使用private来修饰方法, 那么表示这个方法是私有的
可以在类的内部使用

class Person {
    name:string;
    age:number;
    gender:string;
    constructor(name:string, age:number, gender:string){
        this.name = name;
        this.age = age;
        this.gender = gender;
    }
    public sayName():void{
        console.log(`name=${this.name}`);
    }
    protected sayAge():void{
        console.log(`age=${this.age}`);
    }
    private sayGender():void{
        console.log(`gender=${this.gender}`);
    }
    say():void{
        this.sayName();
        this.sayAge();
        this.sayGender();
    }
}
class Student extends Person {
    constructor(name: string, age: number, gender: string) {
        super(name, age, gender);
    }
    say():void{
        this.sayName();
        this.sayAge();
        this.sayGender();
    }
}
let p = new Person('lnj', 34, 'male');
p.say();
p.sayName();
p.sayAge();
p.sayGender();
let stu = new Student('zs', 18, 'female');
stu.say();

需求: 有一个基类, 所有的子类都需要继承于这个基类, 但是我们不希望别人能够通过基类来创建对象
* 
class Person {
    name:string;
    age:number;
    gender:string;
    protected constructor(name:string, age:number, gender:string){
        this.name = name;
        this.age = age;
        this.gender = gender;
    }
    say():void{
        console.log(`name=${this.name},age=${this.age},gender=${this.gender}`);
    }
}
class Student extends Person {
    constructor(name: string, age: number, gender: string) {
        super(name, age, gender);
    }
}
let p = new Person('lnj', 34, 'male');
let stu = new Student('zs', 18, 'female');

4.类的可选属性

// 可选属性
// 和接口中的可选属性一样, 可传可不传的属性
class Person {
    // 注意点: 在TS中如果定义了实例属性, 那么就必须在构造函数中使用, 否则就会报错
    name:string;
    age?:number; // 可选属性
    constructor(name:string, age?:number){
        this.name = name;
        this.age = age;
    }
    // setNameAndAge(name:string, age:number){
    //     this.name = name;
    //     this.age = age;
    // }
}
let p = new Person('lnj');
console.log(p);

5.类的参数属性

// 参数属性
// 一句话搞定实例属性的接收和定义
//完整写法
class Person {
    name:string;
    age:number;
    constructor(name:string, age?:number){
        this.name = name;
        this.age = age;
    }
}
//简单写法
class Person {
    constructor(public name:string,public age:number){
    }
}
let p = new Person('lnj', 34);
console.log(p);

6.类的存取器

1.什么是存取器?
通过getters/setters来截取对对象成员的访问
* */
class Person {
    private _age:number = 0;
    set age(val:number){
        console.log('进入了set age方法');
        if(val<0){
            throw new Error('人的年龄不能小于零');
        }
        this._age = val;
    }
    get age():number{
        console.log('进入了get age方法');
        return this._age;
    }
}
let p = new Person();
p.age = 34;
// p.age = -6; // p.age(-6);
console.log(p.age);