理解 TypeScript 类

对象的设计图:类

在ES5中,只有对象的概念,对象是经过构造函数建立出来的,构造函数自己也是对象。因此说JavaScript是一种基于对象的语言。程序员

ES6以后,有了class,也就是咱们的类,虽然class实质上是 JavaScript 现有的基于原型的继承的语法糖。但咱们一样能够借鉴C#语言的面向对象的思想去理解它。让咱们够使用==基于类的面向对象的方式==。编程

类就是对象的设计图纸,上面记录着一个事物应该有哪些字段,哪些方法,但类不是个对象,只是对象的定义。经过new 一个类,咱们才能获得一个对象,这个对象有类上描述的全部成员。bash

这就是基于类的面向对象的方式。程序员画好了许许多多的设计图(类)。而后new 它们,造成了一个一个的对象,对象之间彼此关联,协做。咱们的程序就这样运行了。函数

因此咱们有了类的概念,通晓类与对象的关系后,这会影响咱们的编程思惟方式,须要什么东西,先定义个类,在new出个对象,让其工做。咱们的对象更加具象了,它有类给予它的定义。学习

认识类

下面咱们就来认识TypeScript中的类ui

定义类

class Person { 
}
复制代码

类中的成员

类内的成员有:字段、存取器、构造函数、方法。this

字段

class Person { 
    age: number; // 这就是一个字段
}
复制代码

类中的变量成员。能够被实例化的对象设置和读取。也能够被类内其余成员设置和读取。spa

存取器

class Person {
    private _age: number;

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

    set age(newName: number) {
        if(newName > 150){
            this._age = 150;
        }
        this._age = newAge;
    }
}
复制代码

这里的get/set方法,就是_age变量的存取器。首先咱们为_age变量添加一个private修饰符。表示它是个私有变量,禁止外部对它的访问。设计

const person = new Person();
person._age // 这句会报错,TS不容许咱们读取私有变量。
复制代码

要想使用_age,须要利用存取器:code

const person = new Person();
person.age = 15; // 使用set age方法
const age = pereson.age; // 使用get age方法
复制代码

使用存取器的好处是对变量的访问和设置,有了控制。原则上类内部的变量,外部是不能访问的,这就是封装性。要想访问,只能经过存取器方法。

构造函数

class Person {
    private _age: number;
    
    constructor(age: number) {
        this._age = age;
    }
}
复制代码

constructor就是类的构造器,他的使用以下:

const person = new Person(15);
复制代码

构造器就是咱们在new一个类的时候,调用的方法。

方法

JavaScript中,都叫函数,可是有了类以后,类中的函数成员,就叫方法。

class Person {
    eat() { 
        ....
    }
    drink() {
        
    }
}
复制代码

这里的eat和drink,就是Person类的方法。

this关键字

和原生js中捉摸不定的this不一样,类中的this,很是好理解,它表示当前类的实例。

类的继承

继承,本质上讲是一种代码重用机制。 类的继承是指一个类继承另外一个类,那么这个类的实例上,也会有被继承类的属性和方法。

class Animal {
    move(distanceInMeters: number = 0) {
        console.log(`Animal moved ${distanceInMeters}m.`);
    }
}

class Dog extends Animal {
    bark() {
        console.log('Woof! Woof!');
    }
}

const dog = new Dog();
dog.bark();
dog.move(10);
dog.bark();
复制代码

extends关键字就是指Dog类继承自Animal类。 Animal叫作父类。Dog叫作子类。

说到类的继承,一样带来了一些问题,须要咱们了解一下。

  1. 父类中有的方法,子类也有,会怎么样?
  2. 子类想使用父类的构造函数,怎么办?

重写

class Animal {
    move(distanceInMeters: number = 0) {
        console.log(`Animal moved ${distanceInMeters}m.`);
    }
}

class Dog extends Animal {
    move(distanceInMeters: number = 0) {
        console.log(`Dog moved ${distanceInMeters}m.`);
    }
    bark() {
        console.log('Woof! Woof!');
    }
}

const dog: Animal = new Dog();
dog.move(10); // Dog moved 10
复制代码

Dog类对Animal的move类进行了重写,调用Dog实例的move方法时,会调用Dog类重写的move方法。

super关键字

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

class Dog extends Animal {
    constructor(name: string) { super(name); }
}
复制代码

若是子类想使用父类中构造函数的逻辑,在子类的构造函数中,super()就是指父类构造函数。

访问修饰符

TypeScript还为咱们提供了类成员的访问修饰符。public,private,protected。表明了成员的三个不一样的访问级别。

  1. public:默认的访问级别,不写默认就是public。
  2. private: 只能被类内部访问,不能被类外部访问。
  3. protected: 只能被类内部,继承的类内部访问,不能被外部访问。

使用方式:

class Person {
    private name: string;
    protected age: string;
    public height: string;
}

const john = new Person("John");
john.name; // 报错
jonh.age; // 报错
jonh.height; // 正确

复制代码

上面看到private和protected在类的外部,都不能够访问,public的能够。那么private和protected有什么区别呢?

class Employee extends Person {
    getInfo() {
        this.name; // 报错
        this.age; // 正确
    }
}
复制代码

区别就在于在继承类中,protected的成员,仍然能够被访问到,可是private的不行。

只读属性

可使用readonly关键字将属性设置成功只读,至关于类字段的const。

class Person {
  readonly name: string = 'john'; // 我只读
  constructor(theName: string) {
    this.name = theName; // 能够
  }

  setName() {
    this.name = 'lili'; // 报错
  }
}
复制代码

只能在初始化和构造函数中赋值,其余地方不容许赋值。

静态属性

类中的成员还能够用static关键字来修饰,那么它就成了全部实例共有的成员。

class Person {
  static globalPeopleCount: number = '7000000000';
}
const john = new Person();
john.globalPeopleCount += 1;

const lili = new Person();
lili.globalPeopleCount // 7000000001

复制代码

抽象类

抽象类是一种不能被实例化的类,它的目的就是用来继承的,抽象类里面能够有抽象的成员,就是本身不实现,等着子类去实现。

抽象类和抽象成员,都是用abstract修饰:

abstract class Animal {
    abstract makeSound(): void;
    move(): void {
        console.log('roaming the earch...');
    }
}
复制代码

抽象类中仍是能够有具体实现的,这样子类若是不实现,能够继承抽象类中的实现。

结束语

学习TS中的类,理解基于类的面向对象思惟,能够帮助咱们更好的应用面向对象思惟,去解决项目的问题。

相关文章
相关标签/搜索