TypeScript 系列(七)—— 类

在 ES6 虽然明确提出了类的概念,我们也能够像传统的面向对象语言那样通过 class 关键字来声明一个类,但是在本质上,这种方式也是会被转换为函数+原型的方式来实现的。所以,在 JS 中,实现面向对象的本质仍然是函数和原型。而且,JS 中没有公有,私有等类的特性,我们不能通过 private 定义一个私有的成员。

然而,TS 就更加像一门传统的面向对象语言呢,怎么说呢?我们从本文来体会吧。

在 TS 中,我们可以通过 class 关键字来定义一个类。

class Person {
    name:string
    age:number
    constructor(name:string,age:number){
        this.name = name
        this.age = age
    }
    sayHi(){
        return `My name is ${this.name},${this.age} years old.`
    }
}

let p = new Person("jonas",18)
console.log(p.sayHi())//My name is jonas,18 years old.

在上面的代码中,定义了一个类 Person ,类中声明了两个属性 name 和 age ,构造器,方法 sayHi 。在类的外面可以通过 new 关键字来生成类的实例化对象,通过实例化对象就可以调用类中的方法。

类的封装性

传统的面向对象语言,类都有三大特性:封装,继承,多态。在 TS 中,类也有封装这个特性。

在 Java 中,封装性主要体现在四种权限修饰符中,通过定义不同的权限从而让属性或者方法对不同的调用者开放或者关闭。在 TS 中,也正是如此。

默认为 public

在前面的例子中,我们并没有为属性或方法声明权限,其实,在 TS 中,缺省修饰符就默认被修饰为 public ,也就是说,显示的加上修饰符 public 和缺省是一样的。

私有的 private

在前面的例子中,我们通过 new 关键字生成了实例 p ,此时因为类中的属性 name 和 age 都是 public 的,所以在类的外面可以通过 对象.属性名 的方式来访问。但是,这不是面向对象的思想,这会破坏了封装性,我们往往对外暴露一个 getter 和 setter 来操作类中的属性,而不是直接的暴露一个属性。

要将这些属性私有化也很简单,跟传统的面向对象语言是一样的,通过 private 关键字来修饰该属性就可以了。

class Person {
    private name:string
    age:number
    constructor(name:string,age:number){
        this.name = name
        this.age = age
    }
    sayHi(){
        return `My name is ${this.name},${this.age} years old.`
    }
}

let p = new Person("jonas",18)
console.log(p.name)//报错!!

从上面的例子来看,加上 private 的属性就不能在外部来访问了,根据面向对象的思想,此时我们应该提供 setter 和 getter 对该属性进行访问。

在 TS 中,我们可以通过关键字 get 和 set 来定义存储器。

class Person {
    private _name:string
    private _age:number

    constructor(name:string,age:number){
        this._name = name
        this._age = age
    }

    get name(): string {
        return this._name;
    }

    set name(value: string) {
        this._name = value;
    }

    get age(): number {
        return this._age;
    }

    set age(value: number) {
        this._age = value;
    }

    sayHi(){
        return `My name is ${this._name},${this._age} years old.`
    }
}

let p = new Person("jonas",18)
console.log(p.name)//jonas
p.name = 'jerry'
console.log(p.name)//jerry

注意,在 TS 中,存储器也是通过 对象.属性 的方式来访问,当进行赋值的时候,会调用 setter ;当进行读取时,会调用 getter 。

readonly  

 可以通过 readonly 关键字来修饰属性,作用就是将这些属性标注为只读的,那么,这些只读属性必须在构造器中进行初始化,一旦进行初始化以后就不能对其进行修改了。

static 

关键字 static 可以用于修饰属性和方法,一旦属性或方法被声明为 static ,那么该属性或方法就不是属于实例对象本身的,而是类本身的。也就是说,这些属性只能通过 类.属性名或方法名 来访问。

抽象类

与 Java 一样,TS 的抽象就是用于定义一个抽象层,可以对某些行为的抽象,也可以对某些行为的实现提供具体细节。但是都有一个特点,抽象类不用于实例化对象,都是通过 abstract 关键字来定义。

你可能感兴趣的:(TypeScript,TypeScript)