首页 > 其他 > 详细

TypeScript - 类

时间:2019-05-17 19:48:24      阅读:113      评论:0      收藏:0      [点我收藏+]

es6中的类

使用 class 定义类,使用 constructor 定义构造函数。通过 new 生成新实例的时候,会自动调用构造函数。

class Animal {
    constructor(name) {
        this.name = name;
    }
    sayHi() {
        return `My name is ${this.name}`;
    }
}

let a = new Animal(Jack);
console.log(a.sayHi()); // My name is Jack

使用 extends 关键字实现继承,子类中使用 super 关键字来调用父类的构造函数和方法。

class Cat extends Animal {
    constructor(name) {
        super(name); // 调用父类的 constructor(name)
        console.log(this.name);
    }
    sayHi() {
        return Meow,  + super.sayHi(); // 调用父类的 sayHi()
    }
}

let c = new Cat(Tom); // Tom
console.log(c.sayHi()); // Meow, My name is Tom

存取器

使用 getter 和 setter 可以改变属性的赋值和读取行为:

class Animal {
    constructor(name) {
        this.name = name;
    }
    get name() {
        return Jack;
    }
    set name(value) {
        console.log(setter:  + value);
    }
}

let a = new Animal(Kitty); // setter: Kitty
a.name = Tom; // setter: Tom
console.log(a.name); // Jack

静态方法

使用 static 修饰符修饰的方法称为静态方法,它们不需要实例化,而是直接通过类来调用:

class Animal {
    static isAnimal(a) {
        return a instanceof Animal;
    }
}

let a = new Animal(Jack);
Animal.isAnimal(a); // true
a.isAnimal(a); // TypeError: a.isAnimal is not a function

es7中的类

ES6 中实例的属性只能通过构造函数中的 this.xxx 来定义,ES7 提案中可以直接在类里面定义:

class Animal {
    name = Jack;

    constructor() {
        // ...
    }
}

let a = new Animal();
console.log(a.name); // Jack

ES7 提案中,可以使用 static 定义一个静态属性:

class Animal {
    static num = 42;

    constructor() {
        // ...
    }
}

console.log(Animal.num); // 42

TypeScript 中类的用法

TypeScript 可以使用三种访问修饰符(Access Modifiers),分别是 publicprivateprotected

  • public 修饰的属性或方法是公有的,可以在任何地方被访问到,默认所有的属性和方法都是 public

  • private 修饰的属性或方法是私有的,不能在声明它的类的外部访问

  • protected 修饰的属性或方法是受保护的,它和 private 类似,区别是它在子类中也是允许被访问的

    class Animal {
        public name;
        public constructor(name) {
            this.name = name;
        }
    }
    
    let a = new Animal(Jack);
    console.log(a.name); // Jack
    a.name = Tom;
    console.log(a.name); // Tom
    class Animal {
        private name;
        public constructor(name) {
            this.name = name;
        }
    }
    
    let a = new Animal(Jack);
    console.log(a.name); // Jack
    a.name = Tom;
    
    // index.ts(9,13): error TS2341: Property ‘name‘ is private and only accessible within class ‘Animal‘.
    // index.ts(10,1): error TS2341: Property ‘name‘ is private and only accessible within class ‘Animal‘.

    上面的例子编译后的代码是:

    var Animal = (function () {
        function Animal(name) {
            this.name = name;
        }
        return Animal;
    }());
    var a = new Animal(Jack);
    console.log(a.name);
    a.name = Tom;

    使用 private 修饰的属性或方法,在子类中也是不允许访问的:

    class Animal {
        private name;
        public constructor(name) {
            this.name = name;
        }
    }
    
    class Cat extends Animal {
        constructor(name) {
            super(name);
            console.log(this.name);
        }
    }
    
    // index.ts(11,17): error TS2341: Property ‘name‘ is private and only accessible within class ‘Animal‘.

    而如果是用 protected 修饰,则允许在子类中访问:

    class Animal {
        protected name;
        public constructor(name) {
            this.name = name;
        }
    }
    
    class Cat extends Animal {
        constructor(name) {
            super(name);
            console.log(this.name);
        }
    }
    抽象类

    abstract 用于定义抽象类和其中的抽象方法。

    抽象类是不允许被实例化的:

    abstract class Animal {
        public name;
        public constructor(name) {
            this.name = name;
        }
        public abstract sayHi();
    }
    
    let a = new Animal(Jack);
    
    // index.ts(9,11): error TS2511: Cannot create an instance of the abstract class ‘Animal‘.

    抽象类中的抽象方法必须被子类实现:

    abstract class Animal {
        public name;
        public constructor(name) {
            this.name = name;
        }
        public abstract sayHi();
    }
    
    class Cat extends Animal {
        public eat() {
            console.log(`${this.name} is eating.`);
        }
    }
    
    let cat = new Cat(Tom);
    
    // index.ts(9,7): error TS2515: Non-abstract class ‘Cat‘ does not implement inherited abstract member ‘sayHi‘ from class ‘Animal‘.

    上面的例子中,我们定义了一个类 Cat 继承了抽象类 Animal,但是没有实现抽象方法 sayHi,所以编译报错了。下面是一个正确使用抽象类的例子:

    abstract class Animal {
        public name;
        public constructor(name) {
            this.name = name;
        }
        public abstract sayHi();
    }
    
    class Cat extends Animal {
        public sayHi() {
            console.log(`Meow, My name is ${this.name}`);
        }
    }
    
    let cat = new Cat(Tom);

    上面的例子中,我们实现了抽象方法 sayHi,编译通过了。需要注意的是,即使是抽象方法,TypeScript 的编译结果中,仍然会存在这个类,上面的代码的编译结果是:

    var __extends = (this && this.__extends) || function (d, b) {
        for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
    var Animal = (function () {
        function Animal(name) {
            this.name = name;
        }
        return Animal;
    }());
    var Cat = (function (_super) {
        __extends(Cat, _super);
        function Cat() {
            _super.apply(this, arguments);
        }
        Cat.prototype.sayHi = function () {
            console.log(Meow, My name is  + this.name);
        };
        return Cat;
    }(Animal));
    var cat = new Cat(Tom);

    给类加上 TypeScript 的类型很简单,与接口类似:

    class Animal {
        name: string;
        constructor(name: string) {
            this.name = name;
        }
        sayHi(): string {
          return `My name is ${this.name}`;
        }
    }
    
    let a: Animal = new Animal(Jack);
    console.log(a.sayHi()); // My name is Jack

     

 

TypeScript - 类

原文:https://www.cnblogs.com/xjy20170907/p/10883039.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!