JavaScript语言基于函数与原型链继承的方式来构建可重用组件。对于OO编程来说会很奇怪,在下一代JavaScript标准(ES6)已经为我们提供OO设计方式。而TypeScript已经实现这种方式,无须等待ES6就可以放心的使用。
类
class Greeter {
greeting: string; // public 属性
constructor(message: string) { // 类构造函数
this.greeting = message;
}
greet() { // public 方法
return "Hello, " + this.greeting;
}
}
// 使用new实例一个Greeter对象
var greeter = new Greeter("world");
和其他语言一样,我们可以在类方法里面使用 this
来代表当前实例的对象。
继承
OO编程最基本就是继承,先来看一个示例:
class Animal {
name: string;
constructor(theName: string) {
this.name = theName;
}
move(meters: number = 0) {
alert(this.name + ‘ moved ‘ + meters + ‘m.‘);
}
}
class Snake extends Animal {
constructor(name: string) {
super(name);
}
move(meters = 5) {
alert(‘Slithering...‘);
super.move(meters);
}
}
class Horse extends Animal {
constructor(name: string) {
super(name);
}
move(meters = 45) { // 重写父类方法
alert(‘Galloping...‘);
super.move(meters); // 调用父类方法
}
}
var sam = new Snake(‘Sammy the Python‘);
var tom: Animal = new Horse(‘Tommy the Palomino‘);
sam.move();
tom.move(34);
案例中和普通类只不过多了一个 extend
来表示类的继承关系,这和接口不同,只允许单一继承。
Private/Public 访问限制
在TypeScript中默认的访问限制为:public,这也就是为什么上面的案例都没有出现 public 字眼。如果想定义私有方法只须在方法前加:private。
class Animal {
private name: string;
constructor(theName: string) {
this.name = theName;
}
say() {
alert(this.name);
}
}
参数属性
参数属性是访问限制另一种简单的写法,比如我们将上面案例改写成:
class Animal {
constructor(private name: string) {
}
say() {
alert(this.name);
}
}
当我们在构造函数里声明一个带有 private
属性时,同时会自动将这个属性初始化成一个类私有属性。
属性访问器
在C#里,可以对某个属性的读和写(即:public string name { get; set; } )操作时执行语句。同样,TypeScript也有类似的实现方式。
class Employee {
private _fullname: string;
get fullname(): string {
return this._fullname;
}
set fullname(newName: string) {
// 做点其它的
this._fullname = newName;
}
}
var employee = new Employee();
employee.fullname = "asdf";
alert(employee.fullname);
静态
通过 static
标记某个属性或方法,这和我其他语言的使用方法一样,其可见性都是为类级访问。
class Grid {
constructor(public scale: number) { }
static origin = { x: 0, y: 0 } // 静态属性
static show() { // 静态方法
alert(‘sho‘);
}
cal(point: { x: number; y: number; }) {
var xDist = (point.x - Grid.origin.x);
var yDist = (point.y - Grid.origin.y);
return Math.sqrt(xDist * xDist + yDist * yDist) / this.scale;
}
}
var grid1 = new Grid(1.0); // 1x scale
var grid2 = new Grid(5.0); // 5x scale
alert(grid1.cal({ x: 10, y: 10 }));
alert(grid2.cal({ x: 10, y: 10 }));