类:
在ts里,我们可以使用常用的面向对象模式。
基于类的设计模式中一种最基本的模式是允许使用继承来扩展现有的类。
默认为public
protected子类可以访问
你可以使用readonly关键字将属性设置为只读的。只读属性必须在声明时或者构造函数里被初始化
参数属性
在上面的例子中,我们不得不定义一个受保护的成员name和一个构造函数参数theName在Person类里,并且立刻将theName的值付给name。
抽象类做为其它派生类的基类使用。他们一般不会直接被实例化。
不同于接口,抽象类可以包含成员的实现细节。
构造函数
当你在TypeScript里声明了一个类的时候,实际上同时声明了很多东西。
如上一节里所讲,类定义会创建两个东西:类的实例类型和一个构造函数。
因为类可以创建出类型,所以你能够在允许使用接口的地方使用类。
class Greeter{
greeting:string;
constructor(message: string){
this.greeting = message;
}
greet(){
return "Hello, " + this.greeting;
}
}
let greeter = new Greeter("world");
继承
在ts里,我们可以使用常用的面向对象模式。
基于类的设计模式中一种最基本的模式是允许使用继承来扩展现有的类。
class Animal{
move(distanceInMeters: number = 0){
console.log('Animal moved ${distanceInMeters}m.');
}
}
class Dog extends Animal{
bark(){
console.log('Woof! Woof!');
}
}
const dog = new Dog();
dog.bark();
dog.move(10);
========================================
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 : number = 0){
console.log('${this.name} moved ${distanceInMeters}m');
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
protected子类可以访问
class Animal{
constructor(private name: string){
}
move(distanceInMeters : number){
console.log(`${this.name} moved ${distanceInMeters}m.`);
}
}
readonly修饰符
你可以使用readonly关键字将属性设置为只读的。只读属性必须在声明时或者构造函数里被初始化
参数属性
在上面的例子中,我们不得不定义一个受保护的成员name和一个构造函数参数theName在Person类里,并且立刻将theName的值付给name。
class Animal{
constructor(private name : string){
}
move(distanceInMeters: number){
//......
}
}
存取器
class Employee{
private _fullName : string;
get fullName():string{
return this._fullName;
}
set fullName(newName : string){
if(password == "password"){
this._fullName = newName;
}else{
console.log("Error: Unauthorized update of employee!");
}
}
}
静态属性
class Gird{
static origin = {x : 0,y: 0};
calculateDistanceFromOrgin(point:{x:number;y:number;}){
let xDist = (point.x - Gird.origin.x);
let yDist = (point.y - Gird.origin.y);
return Math.sqrt(xDist * xDist + yDist * yDist)/this.scale;
}
constructor(public scale: number){
}
}
let grid1 = new Grid(1.0);
let gri = new Grid(5.0);
console.log(grid1.calculateDistanceFromOrigin({x: 10, y: 10}));
抽象类
抽象类做为其它派生类的基类使用。他们一般不会直接被实例化。
不同于接口,抽象类可以包含成员的实现细节。
abstract class Department {
constructor(public name: string) {
}
printName(): void {
console.log('Department name: ' + this.name);
}
abstract printMeeting(): void; // 必须在派生类中实现
}
class AccountingDepartment extends Department {
constructor() {
super('Accounting and Auditing'); // 在派生类的构造函数中必须调用 super()
}
printMeeting(): void {
console.log('The Accounting Department meets each Monday at 10am.');
}
generateReports(): void {
console.log('Generating accounting reports...');
}
}
let department : Department;//允许创建一个对抽象类的引用
department = new Department();//error
department = new AccountingDepartment();
高级技巧
构造函数
当你在TypeScript里声明了一个类的时候,实际上同时声明了很多东西。
class Greeter{
greeting: string;
constructor(message: string){
this.greeting
}
}
把类当做接口使用
如上一节里所讲,类定义会创建两个东西:类的实例类型和一个构造函数。
因为类可以创建出类型,所以你能够在允许使用接口的地方使用类。
class Point{
x : number;
y : number;
}
interface Point3d extends Point{
z:number;
}
let point3d: Point3d = {x:1 ,y:2,z:3};