属性封装

275 阅读2分钟

当我们不希望自己封装的类被自己或别人,随意的更改信息时(比如将年龄改为 -20),我们就要限制类的使用。并在修改信息时,在类中可以拦截并检查

//创建一个 抽象类 Animal
abstract class Animal {
//这里使用 _name,_age 标注为私有变量
   _name: string;
   _age: number;
  constructor(name: string, age: number) {
    this._name = name;
    this._age = age;
  }

//注:get 、set 是js实现的,所以编译后依然存在
//get 函数  ,在读取 name 时,将会调用 name 函数,
//在这里返回 this._name 属性
   get name(): string {
    return this._name;
  }

//set 函数,在设置 age 时,将会调用 age 函数,
//并将设置的值,作用实参传入 age 函数
//在这里可以做些操作
   set age(v: number) {
    if (v > 0) {
      this._age = v;
    }
  }
}

class Dog extends Animal {
  _name: string;
  _age: number;
  constructor(name: string, age: number) {
    super(name, age);
    this._name = name;
    this._age = age;
  }

}

const d = new Dog("小狗", 5);

//当读取name时, name函数就会被调用,并返回 this_name
console.log(d.name);

//当设置 age 时, age函数就会被调用,并返回 this._age
d.age = 5;

可上面这种方式并不可以做到限制访问 _name,_age,这两个属性依然可以访问到
如果 直接 d._name,d._age = -50
这样就无法拦截了。

private 关键字

将属性或方法变为私有的,不允许外部或子类访问

abstract class Animal {
//将 _name,_age 声明为私有属性
  private _name: string;
  private _age: number;
  constructor(name: string, age: number) {
    this._name = name;
    this._age = age;
  }

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

  set age(v: number) {
    console.log(v, "v");

    if (v > 0) {
      this._age = v;
    }
  }
}

//类“Dog”错误扩展基类“Animal”。  
//类型具有私有属性“_name”的单独声明
class Dog extends Animal {
  private _name: string;
  private _age: number;
  constructor(name: string, age: number) {
    super(name, age);
    this._name = name;
    this._age = age;
  }
}

const d = new Dog("小狗", 5);
console.log(d);
console.log(d.name);
d.age = 5;

如果我们希望在子类中访问,可以使用 protected 关键字

注:如果什么都不写,则默认为public 关键字,这是公开的,允许随意访问