面向对象之 class(下)
四种成员可见性
public(类外可见)
public
修饰的属性或方法是公有的,可以在任何地方被访问到,默认所有的属性和方法都是 public
private(类内可见)
private
修饰的属性或方法是私有的,不能在声明它的类的外部访问
protected(子类可见)
protected
修饰的属性或方法是受保护的,它和 private
类似,区别是它在子类中也是允许被访问的
#var(真私有属性)
上面的都是 TS 的语法(访问修饰符),而 #var
是 JS 的语法,在属性名前面加上 #
即可做到真正的属性私有
注意:由于 private
是 TS 的语法,在类型被擦除后就没了;真正的私有属性得使用 #
才能做到
static 属性与 static block
我们可以使用 static
来定义一个静态属性,静态属性只能通过类名来访问
1 2 3 4 5 6 7 8 9 10 11
| class Dog { static kind = "狗";
constructor() { } }
const dog = new Dog(); console.log(dog.kind); console.log(Dog.kind);
|
注意:用 static
声明的属性,其名称不能是 name
、prototype
、length
、arguments
、caller
其中之一
因为 js 中的类都是通过函数来模拟的
static block
主要用来初始化私有属性(类外部无法初始化私有属性)
1 2 3 4 5 6 7 8 9 10
| class Foo { static #count = 0; static { const count = loadFromLocalStorage() || 0; Foo.#count += count; } constructor() { console.log(Foo.#count); } }
|
类与泛型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class Hash<K, V> { map: Map<K, V> = new Map(); set(key: K, value: V) { this.map.set(key, value); } get(key: K) { return this.map.get(key); } }
class Hash<K, V> extends Map<K, V> { destroy() { this.clear(); } }
|
class 表达式
将匿名的 class
赋值给一个变量
1 2 3 4 5 6 7
| const Rectangle = class { constructor(public height: number, public width: number) {} area() { return this.height * this.width; } }; const r = new Rectangle(100, 200);
|
抽象类(不常用)
abstract
用于定义抽象类和其中的抽象方法
抽象类不允许被实例化
1 2 3 4 5 6 7 8
| abstract class Base { abstract getName(): string; printName() { console.log('Hello, ' + this.getName()); } } const b = new Base();
|
抽象类中的抽象方法必须被子类实现,之后才可进行实例化
1 2 3 4 5 6 7 8 9 10 11 12 13
| abstract class Base { abstract getName(): string; printName() { console.log('Hello, ' + this.getName()); } } class Derived extends Base { getName() { return 'world'; } } const d = new Derived(); d.printName();
|
可以看出,抽象类是介于 interface
和 class
之间的一种写法
如果一个 class
中的属性全都是抽象属性,那么也可以直接把这个 class
当作 interface
把类当作参数(常用)
注意是把类作为参数,而不是把类的实例化对象作为参数
1 2 3 4 5 6 7 8 9 10 11 12
| class Person { constructor(public name: string) {} sayHi() { console.log(`Hi, I am ${this.name}`); } } function greet(constructor: typeof Person) { const p = new constructor('ClariS'); p.sayHi(); } greet(Person); greet(new Person('ClariS'));
|
1 2 3 4 5 6 7 8 9 10 11 12
| class Person { constructor(public name: string) {} sayHi() { console.log(`Hi, I am ${this.name}`); } } function greet(constructor: new (name: string) => Person) { const p = new constructor('ClariS'); p.sayHi(); } greet(Person); greet(new Person('ClariS'));
|