TypeScript 类-入门

149 阅读2分钟

TypeScript 类

es6开始 , js 程序员将能够使用基于类的面向对象的方式。自然 ts 也可以

class Greeter {
    greeting : string
    constructor(message : string) {
        this.greeting = message;
    }
    greet() {
        return 'hello' + this.greeting;
    }
}
let g = new Greeter('zs')

继承

在ts里 , 我们可以使用常用的面向对象模式。基于类的程序设计中一种最基本的模式是允许使用继承来扩展现有的类

class Animal {
    move(distance : number = 0) {
        console.log(`Animal move ${distance}`)
    }
}
class Dog extends Animal {
    bark () {
        console.log(`woof woof`)
    }
}
const dog = new Dog();
dog.bark();
dog.move(10)
dog.bark()

这个例子展示了最基本的继承 : 类从基类中继承属性和方法。 派生类通常被称为子类 , 基类通过被称为超类。

下面我们来看个更加复杂的例子:

class Animal {
    name : string
    constructor(theName : string) {
        this.name = theName;
    }
    move(distance : number = 0) {
        console.log(`${this.name} moved ${distance}`)
    }
}

class Snake extends Animal {
    constructor(name : string) {
        super(name);
    }
    move(distance = 5) {
        console.log('Slithering...');
        super.move(distance);
    }
}

class Horse extends Animal {
    constructor(name) {
        super(name);
    }
    move(distance = 45) {
        super.move(distance)
    }
}

let sam = new Snake('Sammy the Python');
let tom : Animal = new Horse('Tommy the')
sam.move(10)

与之前不同点是 , 派生类包含一个构造函数, 它必须调用 super() ,才会继承父类的构造函数中的实例属性。

这个例子演示了如何在子类里可以重写父类方法 . 注意 , 即使 tom 被声明为 Animal 类型 , 但因为它的值是 Horse , 调用 tom.move(34)时 , 它会调用 Horse 重写的方法

公共, 私有 与受保护的修饰符

默认为 public

在上面的例子里, 我们可以自由的访问程序里的定义的成员 ,如果你对其他语言中的类比较了解 , 就会注意到我们在之前的代码里并没有使用 public 来做修饰; 在 TypeScript 里 ,成员都默认为 public

class  Animal {
    public name : string;
    public constructor(name : string) {
        this.name = name;
    }
    public move(distance : number) {
        console.log(`${this.name} moved ${distance}`)
    }
}

理解 private

当成员被标记成 private 时 , 它就不能在声明它的类的外部访问

class Animal {
    private name: string;
    constructor(name) {
        this.name = name;
    }
}

let a = new Animal('hello');// 错误 
a.name

理解 protected

protected 修饰符 与 private 修饰符的行为很相似 , 但有一点不同 , protected 成员在派生类中仍然可以访问.

readonly 修饰符

你可以使用 readonly 关键字将属性设置只读的。 只读属性必须在声明时或构造函数里被初始化

class Octopus {
    readonly name : string;
    readonly number : number = 8;
    constructor(name: string) {
        this.name = name;
    }
}

let da = new Octopus('a')
da.name = 1; // 错误 , name 只是可读的

存取器

TypeScript 支持通过 getters/setters 来截取对象成员的访问。 它能帮助你有效的控制对象成员的访问。
下面看如何把一个简单的类改写成使用 get 和 set.首先 , 我们从一个没有使用存取器的例子开始

let password = 'password';

class Employee {
    public _fullName : string;
    get fullName () : string {
        return this._fullName;
    }

    set fullName(newName : string) {
        if(password && password === 'password') {
            this._fullName = newName;
        } else {
            console.log('Error : update of employee')
        }
    }
}

let e = new Employee();
e.fullName = 'bob'
console.log(e.fullName)

总结

  1. TypeScript 中继承使用 extends , super 指向 父类 , super()继承父类的实例属性 , super.move() 继承父类的原型属性
  2. 类里面的修饰符
    • public : 自己类调用 , 子类调用 , 外部实例调用
    • protected : 自己类调用 , 子类调用
    • private : 自己类调用
    • 默认不加修饰符 , 默认为 public