访问控制修饰符

  • 用来约束某个属性或方法的可返回性 | | 当前类 | 子类 | 示例 | | —- | —- | —- | —- | | private | √ | | | | protected | √ | √ | | | public | √ | √ | √ |
  1. /* 访问控制修饰符 */
  2. class Cat_3201 {
  3. public name: string;
  4. constructor(name: string) {
  5. this.name = name
  6. this.sayHi(); //正确 因为是子类方法
  7. }
  8. protected sayHi(): string {
  9. return 'Hi, ' + this.name;
  10. }
  11. private sayHello(): string {
  12. return 'Hello, ' + this.name;
  13. }
  14. }
  15. let tom_3201 = new Cat_3201('Tom');
  16. tom_3201.name = '123'; //正确 因为是public
  17. tom_3201.sayHello(); //报错 属性“sayHello”为私有属性,只能在类“Cat_3201”中访问
  18. tom_3201.sayHi(); //报错 属性“sayHi”受保护,只能在类“Cat_3201”及其子类中访问。

image.png

答案

A C

解析

private - 被声明的属性(方法)为私有的属性(方法),只能在类 Animal 内部使用。
protected - 被声明的属性(方法)为受保护的属性(方法),即可以在类 Animal 内部使用,也可以在子类中使用。
public - 被声明的属性(方法)为共有的属性(方法),不仅在类 Animal 内部可以使用,也可以在子类和实例中使用。

  • A - age 被修饰为 public,在 getAge 方法中调用用法正确。 getAge 被修饰为 private,在实例 new Animal() 中调用用法错误。
  • B - age 被修饰为 protected,在 getAge 方法中调用用法正确。 getAge 被修饰为 public,在实例 new Animal() 中调用用法正确。
  • C - age 被修饰为 private,在 getAge 方法中调用用法正确。 getAge 被修饰为 protected,在实例 new Animal() 中调用用法错误。
  • D - age 被修饰为 private,在 getAge 方法中调用用法正确。 getAge 被修饰为 public,在实例 new Animal() 中调用用法正确。

只读属性 readonly

  • 用来将一个属性设置为只允许在初始化时赋值

    /* 只读属性 */
    class Cat_3202 {
      private readonly name: string;  // 添加readonly修饰符,一个属性支持多个修饰符
    
      constructor(name: string) {
          this.name = name
      }
      changeName(name: string) {
          this.name = name    //此时报错,因为name是只读属性
      }
      sayHi() {
          return `Hi, ${this.name}`;
      }
    }
    

    image.png

    答案

    D

    解析

    readonly 只能用于修饰属性,不能用于修饰方法。被 readonly 修饰的属性只能初始化阶段赋值和 constructor 中赋值。其他任何方式的赋值都是不被允许的。

  • A - age 被修饰为 private readonly,在 getAge 方法中调用且未发生赋值操作用法正确。 getAge 被修饰为 public,在实例中调用用法正确。

  • B - age 被修饰为 public readonly,未发生赋值操作用法正确。
  • C - age 被修饰为 readonly,在初始化阶段赋值和 constructor 中赋值用法正确。
  • D - age 被修饰为 readonly,在 setAge 方法中赋值用法错误。

静态属性 static

  • 用来讲一个属性或者方法修饰为只能在类上访问,而不是示例上 ```typescript / 静态属性 / class Cat_3203 { static maxAge: number = 38; static setMaxAge(age: number) {

      Cat_3203.maxAge = age;  //可访问类的静态属性,非指向性this,而是指向类本身
    

    }

    private name: string;

    constructor(name: string) {

      this.name = name
    

    } sayHi() {

      return `Hi, ${this.name}`;
    

    } }

let tom_3203 = new Cat_3203(‘Tom’); Cat_3203.maxAge = 40; //正确 因为是静态属性 Cat_3203.setMaxAge(40); //正确 因为是静态方法

![image.png](https://cdn.nlark.com/yuque/0/2022/png/350350/1651815894926-ad106b1c-8cd9-4768-b29f-18fa450599c8.png#clientId=u0692c6db-2a16-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=561&id=u65993b9a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=561&originWidth=912&originalType=binary&ratio=1&rotation=0&showTitle=false&size=117329&status=done&style=none&taskId=u3c9c5b72-bf26-4b1b-a2c4-701bee9629b&title=&width=912)
<a name="TeoSY"></a>
### 答案
A D
<a name="rMD1m"></a>
### 解析
学习完《属性和方法》章节,我们知道类的属性默认是实例属性,类的方法默认是实例方法。<br />TypeScript 中提供了访问修饰符 static 用于定义类的静态属性和方法。静态属性和方法可直接通过类名访问,静态方法中只能访问静态属性和静态方法。

- A - getAge 被修饰为 public static,Animal.getAge() 调用是正确的。age 被修饰为 public static,在静态方法 getAge 中调用静态属性 age 是正确的,故本选项正确。
- B - getAge 被修饰为 public static,Animal.getAge() 调用是正确的。age 被修饰为 public,在静态方法 getAge 中调用实例属性 age 是错误的。故本选项错误。
- C - getAge 被修饰为 public,new Animal().getAge() 调用是正确的。age 被修饰为 public static,在实例方法 getAge 中使用 this.age 是错误的。故本选项错误
- D - getAge 被修饰为 public static,Animal.getAge() 调用是正确的。age 被修饰为 public static,在静态方法 getAge 中调用静态属性 age 是正确的,故本选项正确。

<a name="kCHJ9"></a>
## 抽象类 abstract

- 抽象类不允许实例化
- 抽象方法必须在子类(继承)中实现
```typescript
/* 抽象类 */
// 用来描述抽象概念 无法被实例化 只能被继承
abstract class Animal_3204 {    //abstract抽象类
    name: string;
    sayHi():string {
        return 'Hi'
    }
    abstract sayHello(): string //在定义中不能有具体的实现,只能在继承中实现
}
let animal_3204 = new Animal_3204();  //报错,因为抽象类不能被实例化

// 被实例化的比如猫、狗
class Cat_3204 extends Animal_3204 {
    sayHi() {
        return `Meow, my name is ${this.name}`;
    }
    sayHello(): string {    //这是在继承中实现
        return 'Hello, ' + this.name;
    }
}

class Dog extends Animal_3204 { // 必须得继承abstract方法
    sayHello() {
        return 1    //报错 sayhello必须满足定义的类型string
    }
}

image.png

答案

B

解析

被 abstract 修饰的类为抽象类,在抽象类中被 abstract 修饰的方法为抽象方法。抽象类不能被实例化,抽象类中的抽象方法必须被子类实现。本例中使用 extends 继承了父类 Animal(下章节介绍类继承相关知识)
选项中的 Animal 为抽象类

  • A - 抽象类不能被实例化,故错误。
  • B - 子类 Panda 继承于抽象类 Animal 并实现了抽象方法 getAge,用法正确。
  • C - 子类 Panda 继承于抽象类 Animal,但是未实现抽象方法 getAge,故错误。
  • D - 抽象类 Animal 中的抽象方法 setAge 的函数类型为 public setAge(age: number): void,而子类实现的 setAge 的函数类型为 public setAge(age: string): void,与抽象类所定义的函数类型不相符,故错误。