Typescript 里面定义属性的时候给我们提供了三种修饰符:

  • public:公有,在当前类里面、子类、类外面都可以访问。
  • protected:保护类型,在当前类里面、子类里面可以访问,在类外部没法访问。
  • private:私有,在当前类里面可以访问,子类、类外部都没法访问。

注意:属性如果不加修饰符,默认就是公有(public)。

public

  1. class Person {
  2. public name: string; // 公有
  3. constructor(name: string) {
  4. this.name = name;
  5. }
  6. run(): void {
  7. console.log(`${this.name}在运动`); // 在类里能访问
  8. }
  9. }
  10. let p = new Person("张三");
  11. p.run();
  12. console.log(p.name); // 在类外面能访问
  13. class Child extends Person {
  14. constructor(name: string) {
  15. super(name);
  16. }
  17. run(): void {
  18. console.log(`${this.name}在运动--子类`); // 子类能访问
  19. }
  20. }
  21. let c = new Child("李四");
  22. c.run(); // 李四在运动--子类
  23. console.log(c.name); // 在类外面能访问

protected

  1. class Person {
  2. protected name: string; // 保护
  3. constructor(name: string) {
  4. this.name = name;
  5. }
  6. run(): void {
  7. console.log(`${this.name}在运动`); // 在类里能访问
  8. }
  9. }
  10. let p = new Person("张三");
  11. p.run();
  12. // console.log(p.name); // 报错,在类外面不能访问
  13. class Child extends Person {
  14. constructor(name: string) {
  15. super(name);
  16. }
  17. run(): void {
  18. console.log(`${this.name}在运动--子类`); // 子类能访问
  19. }
  20. }
  21. let c = new Child("李四");
  22. c.run(); // 李四在运动--子类
  23. // console.log(c.name); // 报错,在类外面不能访问

private

  1. class Person {
  2. private name: string; // 私有
  3. constructor(name: string) {
  4. this.name = name;
  5. }
  6. run(): void {
  7. console.log(`${this.name}在运动`); // 在类里能访问
  8. }
  9. }
  10. let p = new Person("张三");
  11. p.run();
  12. // console.log(p.name); // 报错,在类外面不能访问
  13. class Child extends Person {
  14. constructor(name: string) {
  15. super(name);
  16. }
  17. run(): void {
  18. // console.log(`${this.name}在运动--子类`); // 报错,子类不能访问
  19. }
  20. }
  21. let c = new Child("李四");
  22. c.run(); // 李四在运动--子类
  23. // console.log(c.name); // 报错,在类外面不能访问

静态属性和方法

使用 static 修饰符修饰的方法称为静态方法,它们不需要实例化,而是直接通过类来调用,若加上修饰符,和其他属性和方法效果一样。
ES5 中的静态方法、静态属性:

  1. function Person() {
  2. this.run1 = function () {}; // 实例方法,实例化后调用
  3. }
  4. Person.run2 = function () {}; // 静态方法,类名直接调用
  5. Person.name = "lucy"; // 静态属性
  6. Person.run2(); // 静态方法的调用

TypeScript 中的静态方法、静态属性:

  1. class Person {
  2. public name: string;
  3. public age: number = 20;
  4. static sex = "男"; // 静态属性
  5. constructor(name: string) {
  6. this.name = name;
  7. }
  8. run() {
  9. console.log(`${this.name}在运动`);
  10. }
  11. work() {
  12. console.log(`${this.name}在工作`);
  13. }
  14. static print() {
  15. console.log("print静态方法" + Person.sex); // 静态方法,没法直接调用类的属性
  16. }
  17. }
  18. var p = new Person("tony");
  19. p.work();
  20. p.run();
  21. Person.sex; // 男
  22. Person.print();

抽象类

abstract 用于定义抽象类和其中的抽象方法。
什么是抽象类?
首先,抽象类是不允许被实例化的:

  1. abstract class Animal {
  2. public name;
  3. public constructor(name) {
  4. this.name = name;
  5. }
  6. public abstract sayHi();
  7. }
  8. let a = new Animal("tony");

类型 - 图1
上面的例子中,我们定义了一个抽象类 Animal,并且定义了一个抽象方法 sayHi。在实例化抽象类的时候报错了。
其次,抽象类中的抽象方法必须被子类实现:

  1. abstract class Animal {
  2. public name;
  3. public constructor(name) {
  4. this.name = name;
  5. }
  6. public abstract sayHi();
  7. }
  8. class Cat extends Animal {
  9. public eat() {
  10. console.log(`${this.name} is eating.`);
  11. }
  12. }
  13. let cat = new Cat("Tom");

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

  1. abstract class Animal {
  2. public name;
  3. public constructor(name) {
  4. this.name = name;
  5. }
  6. public abstract sayHi();
  7. }
  8. class Cat extends Animal {
  9. public sayHi() {
  10. alert(`Meow, My name is ${this.name}`);
  11. }
  12. }
  13. let cat = new Cat("Tom");
  14. cat.sayHi();