类描述了所创建的对象共同的属性和方法。通过
class
关键字声明一个类,主要包含以下模块:
- 属性
- 构造函数
- 方法
属性和方法
使用 class
定义类,使用 constructor
定义构造函数。
通过 new
生成新实例的时候,会自动调用构造函数。
class Animal {
public name;
constructor(name) {
this.name = name;
}
sayHi() {
return `My name is ${this.name}`;
}
}
let a = new Animal('Jack');
console.log(a.sayHi()); // My name is Jack
存取器
TypeScript支持通过getters/setters
来截取对对象成员的访问。 它能帮助你有效的控制对对象成员的访问。
class Animal {
constructor(name) {
this.name = name;
}
get name() {
return 'Jack';
}
set name(value) {
console.log('setter: ' + value);
}
}
let a = new Animal('Kitty'); // setter: Kitty
a.name = 'Tom'; // setter: Tom
console.log(a.name); // Jack
类的继承与重写
使用 extends
关键字实现继承,子类中使用 super
关键字来调用父类的构造函数和方法。这样可以抽出公共部分让子类复用。
重写就是子类可以重新编写父类里边的代码。
class Animal {
name: string;
constructor(theName: string) { this.name = theName; }
move(distanceInMeters: number = 0) {
console.log(`${this.name} moved ${distanceInMeters}m.`);
}
}
class Snake extends Animal {
constructor(name: string) { super(name); }
move(distanceInMeters = 5) {
console.log("Slithering...");
super.move(distanceInMeters);
}
}
class Horse extends Animal {
constructor(name: string) { super(name); }
move(distanceInMeters = 45) {
console.log("Galloping...");
super.move(distanceInMeters);
}
}
let sam = new Snake("Sammy the Python");
let tom: Animal = new Horse("Tommy the Palomino");
sam.move();
tom.move(34);
访问修饰符
public
public
修饰的属性或方法是公有的,在程序类的内部和外部都可以访问。类的成员全部默认为 public
。
class Animal {
public name;
public constructor(name) {
this.name = name;
}
}
let a = new Animal('Jack');
console.log(a.name); // Jack
a.name = 'Tom';
console.log(a.name); // Tom
private
private
修饰的属性或方法是私有的,不能在声明它的类的外部访问,只能被类的内部访问,在子类中也不允许访问。
当构造函数修饰为 private 时,该类不允许被继承或者实例化:
protected
protected
修饰的属性或方法是受保护的,只能被类的内部以及类的子类访问。
class Animal {
protected name;
public constructor(name) {
this.name = name;
}
}
class Cat extends Animal {
constructor(name) {
super(name);
console.log(this.name); // name 在子类中允许访问
}
}
当构造函数修饰为 protected 时,该类允许被继承,不允许被实例化:
readonly
通过 readonly 关键字将属性设置为只读的。只读属性必须在声明时或构造函数里被初始化。
静态方法
使用 static
修饰符修饰的方法称为静态方法,它们不需要实例化,而是直接通过类来调用,类的实例无法访问:
静态方法调用同一个类中的其他静态方法,可使用 this
关键字:
class StaticMethodCall {
static staticMethod() {
return 'Static method has been called'
}
//静态方法中的 this 指向类本身,而静态方法也存在于类本身
//所以可以在静态方法中用 this 访问在同一类中的其他静态方法
static anotherStaticMethod() {
return this.staticMethod() + ' from another static method'
}
}
非静态方法中,不能直接使用 this
关键字来访问静态方法。而要用类本身或者构造函数的属性来调用该方法:
class StaticMethodCall {
constructor() {
// 类本身调用
console.log(StaticMethodCall.staticMethod())
// 构造函数的属性调用
console.log(this.constructor.staticMethod())
}
static staticMethod() {
return 'static method has been called.'
}
}
类指向其构造函数本身,在非静态方法中,this.constructor === StaticMethodCall 为 true
抽象类
abstract
用于定义抽象类、抽象类内部定义抽象方法。
抽象类不允许被实例化,抽象类中的抽象方法必须被子类实现
抽象类中的抽象方法被子类实现后不报错了
把类当做接口使用
class Point {
x: number;
y: number;
}
interface Point3d extends Point {
z: number;
}
let point3d: Point3d = {x: 1, y: 2, z: 3};
总结
- 类指向其构造函数本身。
- 静态方法存在于类本身上面而不是类的实例上。
- 抽象类中的抽象方法不包含具体实现并且必须在派生类中实现。
- TypeScript 新增了 public、protected、private 等访问修饰符。
- 子类继承父类时,在其构造函数 constructor() 中不要忘了 super() 方法。