本文共 3755 字,大约阅读时间需要 12 分钟。
class Grid { static origin = {x: 0, y: 0}; calculateDistanceFromOrigin(point: {x: number; y: number;}) { let xDist = (point.x - Grid.origin.x); let yDist = (point.y - Grid.origin.y); return Math.sqrt(xDist * xDist + yDist * yDist) / this.scale; } constructor (public scale: number) { }}let grid1 = new Grid(1.0); // 1x scalelet grid2 = new Grid(5.0); // 5x scaleconsole.log(grid1.calculateDistanceFromOrigin({x: 10, y: 10}));console.log(grid2.calculateDistanceFromOrigin({x: 10, y: 10}));
abstract class Animal { abstract makeSound(): void; move(): void { console.log('roaming the earch...'); }}
重点说一下抽象类的抽象方法
abstract
关键字并且可以包含访问修饰符。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(); // 错误: 不能创建一个抽象类的实例department = new AccountingDepartment(); // 允许对一个抽象子类进行实例化和赋值department.printName();department.printMeeting();department.generateReports(); // 错误: 方法在声明的抽象类中不存在,注意此处报错是因为一开始声明let department: Department; 。并不是说抽象类的子类不能有自己的方法
打印结果
构造函数
当你在TypeScript里声明了一个类的时候,实际上同时声明了很多东西。 首先就是类的 实例的类型。
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());
这里,我们写了 let greeter: Greeter
,意思是 Greeter
类的实例的类型是 Greeter
。 这对于用过其它面向对象语言的程序员来讲已经是老习惯了。
我们也创建了一个叫做 构造函数的值。 这个函数会在我们使用 new
创建类实例的时候被调用。 下面我们来看看,上面的代码被编译成JavaScript后是什么样子的:
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());
上面的代码里, let Greeter
将被赋值为构造函数。 当我们调用 new
并执行了这个函数后,便会得到一个类的实例。 这个构造函数也包含了类的所有静态属性。 换个角度说,我们可以认为类具有 实例部分与 静态部分这两个部分。
让我们稍微改写一下这个例子,看看它们之间的区别:
class Greeter { static standardGreeting = "Hello, there"; greeting: string; greet() { if (this.greeting) { return "Hello, " + this.greeting; } else { return Greeter.standardGreeting; } }}let greeter1: Greeter;greeter1 = new Greeter();console.log(greeter1.greet());let greeterMaker: typeof Greeter = Greeter;greeterMaker.standardGreeting = "Hey there!";let greeter2: Greeter = new greeterMaker();console.log(greeter2.greet());
这个例子里, greeter1
与之前看到的一样。 我们实例化 Greeter
类,并使用这个对象。 与我们之前看到的一样。
再之后,我们直接使用类。 我们创建了一个叫做 greeterMaker
的变量。 这个变量保存了这个类或者说保存了类构造函数。 然后我们使用 typeof Greeter
,意思是取Greeter类的类型,而不是实例的类型。 或者更确切的说,"告诉我 Greeter
标识符的类型",也就是构造函数的类型。 这个类型包含了类的所有静态成员和构造函数。 之后,就和前面一样,我们在 greeterMaker
上使用 new
,创建 Greeter
的实例。
把类当做接口使用
如上一节里所讲的,类定义会创建两个东西:类的实例类型和一个构造函数。 因为类可以创建出类型,所以你能够在允许使用接口的地方使用类。
class Point { x: number; y: number;}interface Point3d extends Point { z: number;}let point3d: Point3d = {x: 1, y: 2, z: 3};
转载地址:http://tuvm.baihongyu.com/