修饰符
public
- 在TypeScript里,成员都默认为
public
private
-
当成员被标记成
private
时,只能在声明它的类的内部访问class Animal { private name: string; constructor(theName: string) { this.name = theName; } } new Animal("Cat").name; // 错误: 'name' 是私有的.
-
当我们比较带有
private
或protected
成员的类型的时候,如果其中一个类型里包含一个private/protected
成员,那么另外一个类型中也必须存在这样一个private/protected
成员, 并且它们都是来自同一处声明时,这两个类型才是兼容的class Animal { private name: string; constructor(theName: string) { this.name = theName; } } class Rhino extends Animal { constructor() { super("Rhino"); } } class Employee { private name: string; constructor(theName: string) { this.name = theName; } } let animal = new Animal("Goat"); let rhino = new Rhino(); let employee = new Employee("Bob"); animal = rhino; animal = employee; // 错误: Animal 与 Employee 不兼容. 因为Employee的name来源与Animal不同
protected
-
与
private
修饰符的行为很相似,但有一点不同,protected
成员除了可以在声明它的类的内部访问,在派生类中仍然可以访问class Person { protected name: string; constructor(name: string) { this.name = name; } } class Employee extends Person { constructor(name: string) { super(name) } public getElevatorPitch() { return `Hello, my name is ${this.name}`; // 在派生类中正常访问 } } let howard = new Employee("Howard"); console.log(howard.getElevatorPitch()); console.log(howard.name); // 错误 在外部无法访问
-
构造函数也可以被标记成
protected
, 这意味着这个类不能在包含它的类外被实例化,但是能被继承class Person { protected name: string; protected constructor(theName: string) { this.name = theName; } } // Employee 能够继承 Person class Employee extends Person { private department: string; constructor(name: string, department: string) { super(name); this.department = department; } public getElevatorPitch() { return `Hello, my name is ${this.name} and I work in ${this.department}.`; } } let howard = new Employee("Howard", "Sales"); let john = new Person("John"); // 错误: 'Person' 的构造函数是被保护的.
readonly
-
只读属性必须在声明时或构造函数里被初始化
class Octopus { readonly name: string; readonly numberOfLegs: number = 8; constructor (theName: string) { this.name = theName; } } let dad = new Octopus("Man with the 8 strong legs"); dad.name = "Man with the 3-piece suit"; // 错误! name 是只读的.
参数属性
-
参数属性可以在将成员的声明和赋值合并至构造函数内
// 未使用参数属性 class Octopus { readonly name: string; constructor (theName: string) { this.name = theName; } } // 使用参数属性,省略了theName,将声明和初始化合成一步 class Octopus { // readonly 修饰符可以替换成private,public或protected constructor(readonly name: string) { } }
静态属性
-
通过
static
关键字定义,通过类名访问class Grid { static origin = { x: 0, y: 0 }; } console.log(Grid.origin.x);
抽象类
不能直接被实例化,作为其它派生类的基类使用,与接口类似,不同在于抽象类可以包含成员的实现细节;
-
通过
abstract
关键字是定义抽象类和在抽象类内部定义抽象方法abstract class Animal { abstract makeSound(): void; move(): void { console.log('roaming the earch...'); } }
抽象类中的抽象方法不包含具体实现并且必须在派生类中实现,在派生类的构造函数中必须调用 super()
构造函数
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
let greeter: Greeter;
greeter = new Greeter("world");
console.log(greeter.greet());
编译成js后
let Greeter = (function () {
function Greeter(message) {
this.greeting = message;
}
Greeter.prototype.greet = function () {
return "Hello, " + this.greeting;
};
return Greeter;
})();
let greeter;
greeter = new Greeter("world");
console.log(greeter.greet());