typescript入门笔记2

106 阅读3分钟

类 Class

传统的js中使用函数和基于原型的继承来创建可复用的组件。ES6开始,能够使用基于类的面向对象的方式,ts也支持基于类的面向对象的方式。

可以理解为模板,通过模板可以实例化对象

面向对象的编程思想

基本示例

class Greeter {
    // 声明属性
    message: string
    // 构造函数:为了将来实例化对象的时候,可以直接对属性的值进行初始化
    constructor(message: string) {
        this.message = message
    }
    // 一般方法
    sayHello(): string {
        return 'Hello' + this.message;
    }

}

// 创建类的实例
const greeter = new Greeter('word')

// 调用实例
console.log(greeter.sayHello())

继承

类与类之前的关系,A类继承了B这个类,那么此时A类叫子类(派生类),B类叫基类(超类、父类)

class Person{
    // 定义属性
    name: string
    age: number
    gender: string
    // 定义构造函数
    constructor(name: string="小红", age: number=20, gender: string="女") {
        this.name = name;
        this.age = age;
        this.gender = gender
    }
    // 定义实例方法
    sayHi(str: string){
        console.log(`我是${this.name},${str}`)
    }
}

class Student extends Person {
    constructor(name: string, age: number, gender: string) {
        // 调用的是父类中的构造函数,使用的是super
        super(name, age, gender);
    }
    sayHi(){
        super.sayHi('里斯')
    }
}

const person = new Person('小明', 50, '男')
const stu = new Student(‘晓晓’, 12, ‘女’);

多态

父类型的引用指向子类型的对象,不同类型的对象针对相同的方法,产生了不同的行为

class Animal {
    name: string
    constructor(name: string) {
        this.name = name
    }
    run(distance: number){
        console.log(`跑了${distance} 米这么远的距离`, this.name)
    }
}

class Dog extends Animal {
    constructor(name: string) {
        super(name)
    }
    run(distance: number = 5){
        console.log(`跑了${distance} 米这么远的距离`, this.name)
    }

}

class Pig extends Animal {
    constructor(name: string) {
        super(name)
    }
    run(distance: number = 10){
        console.log(`跑了${distance} 米这么远的距离`, this.name)
    }
}

// 实例化子类对象
const dog: Animal = new Dog('小灰')
dog.run() // 5, 小灰

// 实例化子类对象
const pig: Animal = new Pig('佩奇')
pig.run() // 10, 佩琦

公共,私有与受保护的修饰符(public/private/protected)

描述类中的成员(属性,构造函数,方法)的可访问性,默认为public。

// 属性修饰
class Animal {
    // private name: string //私有属性,外部无法访问,子类也无法访问
    // public name: string //公共属性,任何位置都可以访问
    protected name: string //受保护的属性,外部无法访问,子类中可以访问
    constructor(name: string) {
        this.name = name
    }
    run(distance: number){
        console.log(`跑了${distance} 米这么远的距离`, this.name)
    }
}

// 构造函数参数修饰
class Person {
    // 修饰后name参数称为参数属性,Person中就存在一个公共name的属性成员,private和protected一致
    constructor(public name: string='xxx') {
        this.name = name
    }
}

readonly修饰符

一个关键字,对类中的属性成员进行修饰。

// 属性修饰,修饰后该属性成员不能被外部随意修改。初始化及构造函数中可以修改。
class Person {
    readonly name: string
    constructor(name: string='xxx') {
        this.name = name
    }
    sayHi() {
        console.log('哈利阿斯哟', this.name)
    }
}

//构造函数参数修饰,该属性成员不能被外部随意修改
class Person {
    // 修饰后name参数称为参数属性,Person中就存在一个name的属性成员
    constructor(readonly name: string='xxx') {
        this.name = name
    }
}

存取器

支持通过getter/setter来劫持对象成员的访问。

class Person {
    firstName: string = 'A'
    lastName: string = 'B'

    //负责读取
    get fullName() {
        return this.firstName + '-' + this.lastName
    }

    //负责设置
    set fullName(val: string) {
        let names = val.split('-')
        this.firstName = names[0]
        this.lastName = names[1]
    }
}

const per = new Person();

per.fullName = 'E-F'
console.log(per.firstName) // E

静态成员

在类中通过static修饰的属性或者方法,通过类名.来调用

class Person {
    static name: string = '小红'
    constructor(name: string) {
        this.name = name // error 构造函数不能通过static进行修饰
    }
    sayHi() {
        console.log('hello')
    }
}

console.log(Person.name) // 小红
console.log(Person.sayHi()) // hello

抽象类

抽象方法不能有任何具体内容的实现。做为其他派生类的基类使用,不能被实例化。通过abstract关键字定义抽象类和在抽象内部定义抽象方法。为了让子类进行实例化及实现内部抽象方法。

抽象类的作用就是为子类存在的。

abstract class Animal{
    // 抽象类
    abstract eat()
    // 实例方法
    sayHi() {
        console.log(‘hello')
    }
}

class Dog extends Animal {
    // 重新实现抽象类中的方法,是Dong类的实例方法
    eat() {
        console.log('趴着吃')
    }
}