您的位置:首页 > Web前端 > JavaScript

TypeScript与JavaScript不同之处系列(三) ===> 类

2020-04-05 07:16 561 查看

本系列目的: 列出TypeScript与JavaScript的不同点, 缩小文档内容, 提高学习速度. 原文档地址: https://www.tslang.cn/index.html

全系列目录

文章目录

  • 2. 抽象类
  • 3. 把类当初接口
  • 1. 类

    1.1. 简单使用

    在TypeScript里,成员都默认为 public, 成员可以额被标记 private, protected, 或者static

    // --------------------- public
    class Animal {
    name: string;
    constructor(theName: string) { this.name = theName; }
    move(distanceInMeters: number = 0) {
    console.log(`${this.name} moved ${distanceInMeters}m.`);
    }
    }
    
    // --------------------- public 同上
    class Animal {
    public name: string;
    public constructor(theName: string) { this.name = theName; }
    public move(distanceInMeters: number) {
    console.log(`${this.name} moved ${distanceInMeters}m.`);
    }
    }
    
    // --------------------- private
    class Animal {
    private name: string;
    constructor(theName: string) { this.name = theName; }
    }
    
    new Animal("Cat").name; // 错误: 'name' 是私有的.
    
    // --------------------- protected
    class Person {
    protected name: string;
    constructor(name: string) { this.name = name; }
    }
    
    class Employee extends Person {
    private department: string;
    
    constructor(name: string, department: string) {
    super(name)
    this.department = department;
    }
    
    public getElevatorPitch() {
    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); // 错误
    
    // --------------------- static
    class Grid {
    static origin = {x: 0, y: 0};
    calculateDistanceFromOrigin(point: {x: number; y: number;}) {
    let xDist = (point.x - Grid.origin.x);
    let yDist = (point.y - Grid.origin.y);
    return Math.sqrt(xDist * xDist + yDist * yDist) / this.scale;
    }
    constructor (public scale: number) { }
    }
    
    let grid1 = new Grid(1.0);  // 1x scale
    let grid2 = new Grid(5.0);  // 5x scale
    
    console.log(grid1.calculateDistanceFromOrigin({x: 10, y: 10}));
    console.log(grid2.calculateDistanceFromOrigin({x: 10, y: 10}));

    1.2. readonly修饰符

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

    class Octopus {
    readonly name: string;
    readonly numberOfLegs: number = 8;
    constructor (theName: string) {
    this.name = theName;
    }
    }
    let dad = new Octopus("Man with the 8 strong legs");
    dad.name = "Man with the 3-piece suit"; // 错误! name 是只读的.
    
    // --------------------------- 也可以省略成这样
    
    class Octopus {
    readonly numberOfLegs: number = 8;
    constructor(readonly name: string) {
    }
    }

    1.3. 存取器

    这个在es2015也有, 复习一下.
    注意在编译的时候要用

    tsc -t es5
    命令输出es5,
    tsc
    命令会报错

    let passcode = "secret passcode";
    
    class Employee {
    private _fullName: string;
    
    get fullName(): string {
    return this._fullName;
    }
    
    set fullName(newName: string) {
    if (passcode && passcode == "secret passcode") {
    this._fullName = newName;
    }
    else {
    console.log("Error: Unauthorized update of employee!");
    }
    }
    }
    
    let employee = new Employee();
    employee.fullName = "Bob Smith";
    if (employee.fullName) {
    alert(employee.fullName);
    }

    2. 抽象类

    抽象类做为其它派生类的基类使用。 它们一般不会直接被实例化。 不同于接口,抽象类可以包含成员的实现细节。 abstract关键字是用于定义抽象类和在抽象类内部定义抽象方法。(此处类似java)

    abstract class Animal {
    abstract makeSound(): void;
    move(): void {
    console.log('roaming the earch...');
    }
    }
    
    // 如果Animal作为类型去用的话, 不可以使用抽象类里没有的属性
    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(); // 错误: 方法在声明的抽象类中不存在

    3. 把类当初接口

    与java语言不同的是, ts接口可以继承类.
    类定义会创建两个东西:类的实例类型和一个构造函数。 因为类可以创建出类型,所以你能够在允许使用接口的地方使用类. 即使类里面可以实现方法, 但在interface继承了之后下面这个例子中的point3d变量还需要自己再实现一次.

    class Point {
    x: number;
    y: number;
    }
    
    interface Point3d extends Point {
    z: number;
    }
    
    let point3d: Point3d = {x: 1, y: 2, z: 3};
    
    // ---------------------------
    
    class Point {
    x: number;
    y: number;
    public gkd() : string {
    return 'aasd';
    };
    }
    
    interface Point3d extends Point {
    z: number;
    }
    
    let point3d: Point3d = { x: 1, y: 2, z: 3, gkd: ():string => {
    return '123';
    } };
    • 点赞
    • 收藏
    • 分享
    • 文章举报
    刘翾 博客专家 发布了167 篇原创文章 · 获赞 275 · 访问量 59万+ 他的留言板 关注
    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: