使用类的例子:
class Greeter{
greeting: string;
constructor(message: string){
this.greeting = message;
}
greet(){
return 'hello, ' + this.greeting;
}
}继承
class Animal{
move(distanceInMeters: number = 0){
console.log(`Animal moved ${ distanceInMeters }`)
}
}
class Dog extends Animal{
bark(){
console.log('Woof! Woof!!!')
}
}
const dog = new Dog();
dog.brak();
dog.move(10);
dog.brak();类从基类中继承属性和方法。这里的Dog是一个派生类,它派生自Animal基类,通过extends关键字。派生类通常被称作子类,基类通常被称为超类。
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);与前一个例子不同的是,派生类包含了一个构造函数,它必须调用super(), 它会执行基类的构造函数。而且在构造函数里访问this的属性之前,我们一定要调用super()。这是TypeScript强制执行的一条重要规定。
公共,私有与受保护的修饰符
默认public
使用public重写Animal
class Animal{
public name: string;
public constructor(theName: string){ this.name = theName }
public move(distanceInMeters: number){
console.log(`${this.name} moved ${ distanceInMeters }`)
}
}理解private
当成员被标记为private时,他就不能再类外面访问了。
class Animal{
private name: string;
constructor(theName: string){ this.name = theName}
}
new Animal('Cat').name; //errorTypeScript使用的是结构类型系统。
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; //error;理解protected
protected修饰符与private修饰符的行为很相似,但有一点不同,protected成员在派生类中任然可以访问。
class Person{
protected name: string;
constructor(name: string){ this.name = name }
}
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");
console.log(howard.getElevatorPitch());
console.log(howard.name); //error注意:我们不能再Person外使用name,但可以在它的派生类中重写name;
构造函数也可以被标记为protected。意味着这个类不能在包含它的类外部实例化,但是可以被继承。
class Person{
protected name: string;
protected constructor(theName: string){ this.name = theName }
}
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"); //errorreadonly修饰符
可以使用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"; //error;存取器
TypeScript支持通过getters/setters来截取对象成员的访问。
letpasscod = "secret passcod";
class Employee{
private _fullName: string;
get fullName(): string{
return this._fullName;
}
set fullName(newName: string){
if(passcode && passcode == 'secret passcod'){
this._fullName = newName;
}else{
console.log("Error: Unauthorized update of employee!");
}
}
}
let employee = new Employee();
employee.fullName = "Bob smith";
if(employee.fullName){
alert(employee.fullName);
}