TypeScript学习笔记-类

161 阅读1分钟

class Greeter {
    greeting: string;
    constructor (message: string) {
        this.greeting = message;
    } 
    greet () {
        return `Hello, ${this.greeting}`;
    }
}
let greeter = new Greeter('World');
console.log(greeter.greet());

继承

class Animal {  // Animal 是基类或超类
    name: string;
    constructor (name: string) {
	    this.name = name;
    }

    move (distanceInMeters: number = 0): string {
        return `${this.name} moved ${distanceInMeters}m.`;
    }
}
class Dog extends Animal {  // Dog 是派生类
    constructor (name) {
    super(name);  // 执行基类构造函数,访问 this的属性之前,我们 一定要调用 super()
    }

    bark (): string {
    return 'Woof! Woof!';
    }

    move (distanceInMeters = 20): string {
    return super.move(distanceInMeters);  // 基类move方法
    }
}
const dog = new Dog('Lili')
console.log(dog.bark());
console.log(dog.move(100));

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

// public: 成员都默认为 public
class AnimalPulic {  // 明确的将一个成员标记成 public
    public name: string;
    public constructor (name: string) {
        this.name = name;
    }
    public move (distanceInMeters: number = 0): string {
        return `${this.name} moved ${distanceInMeters}m.`;
    }
}

// private: 不能在声明它的类的外部访问, private成员在派生类中仍然可以访问
class AnimalPrivate {
    private name: string;  // 不能在声明它的类的外部访问
    public constructor (name: string) {
        this.name = name;
    }
    public move (distanceInMeters: number = 0): string {
        return `${this.name} moved ${distanceInMeters}m.`;
    }
}
console.log(new AnimalPrivate("Cat").name);  // Property 'name' is private and only accessible within class 'AnimalPrivate'.

// protected: 与 private修饰符的行为很相似, 但protected成员在派生类中仍然可以访问
class Person {
    protected name: string;
    protected constructor (name: string) {  // 构造函数被标记成protected,这个类不能在包含它的类外被实例化,但是能被继承
        this.name = name;
    }
}
class Employee extends Person {
    private department: string;
    constructor (name, department) {
        super(name);
        this.department = department;
    }
    public getElevatorPitch(): string {
        return `Hello, my name is ${this.name} and I work in ${this.department}.`;
    }
} 
let howard = new Employee('Howard', 'Sales');
console.log(howard.getElevatorPitch());
console.log(howard.name);  // Property 'name' is protected and only accessible within class 'Person' and its subclasses.
console.log(new Person("John"));  // Constructor of class 'Person' is protected and only accessible within the class declaration.

readonly修饰符

// 使用 readonly关键字将属性设置为只读的,只读属性必须在声明时或构造函数里被初始化。
class Octopus {
    readonly numberOfLegs: number = 8;
    constructor (private name: string) {} // 参数name使用了参数属性,在一个地方定义并给初始化一个成员(包括属性和赋值)
}
let dad = new Octopus('Man with the 8 strong legs');
dad.name = 'Man with the 3-piece suit';  // Cannot assign to 'name' because it is a constant or a read-only property.

存取器:get、set

// 通过getters/setters来截取对对象成员的访问
// 只带有 get不带有 set的存取器自动被推断为 readonly

// 运行下面代码可能会报:Accessors are only available when targeting ECMAScript 5 and higher.
// 解决:在命令后加 --target ES5
class EmployeeGetSet {
    private _fullName: string;
    get fullName (): string {
        return this._fullName;
    }
    set fullName (_fullName: string) {
        this._fullName = _fullName;
    }
}
let employeeGetSet = new EmployeeGetSet();
employeeGetSet.fullName = 'Tom';
console.log(employeeGetSet.fullName);

静态属性

// 存在于类本身上面而不是类的实例上
class Gird {
    static origin = {
        x: 0,
        y: 0
    }
    constructor (public scale: number) {}  // scale 使用参数属性
    calculateDistanceFromOrigin (point: {x: number, y: number}) {
        let xDist = (point.x - Gird.origin.x);  // 静态属性调用
        let yDist = (point.y - Gird.origin.y);
        return Math.sqrt(xDist * xDist + yDist * yDist) / this.scale;
    }
}

抽象类

// 抽象类做为其它派生类的基类使用,抽象类可以包含成员的实现细节,一般不会直接被实例化。
abstract class AnimalAbstract {  // 定义抽象类
    constructor(public name: string) {}
    abstract makeSound() : string;  // 定义抽象方法,不包含具体实现并且必须在派生类中实现
}
class Sheep extends AnimalAbstract {
    constructor(name) {
        super(name);
    }
    makeSound (): string {
        return `A Sheep named ${name}, sounds mie mie~`;
    }
    moved () {
        return `A Sheep named ${name}, moved 8km`;
    }
}
let sheep: AnimalAbstract;  // 创建一个对抽象类型的引用
sheep = new Sheep('Hary');
console.log(sheep.makeSound());
console.log(sheep.moved());  // Property 'moved' does not exist on type 'AnimalAbstract'. 因为对象是对抽象类的引用,方法在声明的抽象类中不存在