传统的javascript使用函数来创建可重用的组件,而熟悉面向对象设计和开发的则更加熟悉类/接口/集成等面向对象的方式。而这些在ECMAScript 2015得到了支持,javascript也可以使用面向对象的设计方法了,但是在ES5尚未完全得到全部支持的现在,通过使用typescript了先行使用此类特性在我们的项目之中。
由于面向对象的编程已经是极为基础,我们只需要看一下typescript中是如何实现的即可。我们将会通过几个简单的例子来研究一下相关的基本使用方法。
Animal类
这篇文章的例子,将会写在一个名为class-practice.ts的文件之中。首先我们先在这个文件之中实现一个Animal的类。
[root@angular proj]# grep class tsconfig.json
"src/class-practice.ts"
[root@angular proj]#
[root@angular proj]# cat src/class-practice.ts
class Animal {
public name: string;
public constructor(theName: string) { this.name = theName; }
public move(distanceInMeters: number) {
console.log(${
this.name} moved ${distanceInMeters}m.);
}
}
let animal = new Animal("Dog");
animal.move(100);
[root@angular proj]#
编译&结果确认
[root@angular proj]# gulp
[07:14:13] Using gulpfile /tmp/proj/gulpfile.js
[07:14:13] Starting 'default'...
[07:14:22] Finished 'default' after 9.17 s
[root@angular proj]# node dist/class-practice.js
Dog moved 100m.
[root@angular proj]#
确认编译生成的js代码:
[root@angular proj]# cat dist/class-practice.js
var Animal = /** @class */ (function () {
function Animal(theName) {
this.name = theName;
}
Animal.prototype.move = function (distanceInMeters) {
console.log(this.name + " moved " + distanceInMeters + "m.");
};
return Animal;
}());
var animal = new Animal("Dog");
animal.move(100);
[root@angular proj]#
Animal的类写的非常的简单,但是从这几行简单的代码中,我们可以了解到typescript的一些使用的特点:
- 成员函数需要用this指针进行引用
- 修饰符也是有public/private/protected三种
- 缺省的情况下,成员时public的
- private只能在定义的类中进行使用
- protected能够在定义的类和继承的类中使用,但不能在实例中直接引用
- 整体的类等相关使用方式和C#或者C++非常类似
- readonly修饰符设定只读属性,只能在声明或者构造函数中被初始化
- 虚函数的使用也同C++大同小异
Horse类
稍微对程序进行修改,创建一个Horse类继承Animal类,同时将Animal类的name设定为protected方式。具体代码如下:
[root@angular proj]# cat src/class-practice.ts
class Animal {
protected name: string;
public constructor(theName: string) { this.name = theName; }
public move(distanceInMeters: number) {
console.log(${
this.name} moved ${distanceInMeters}m.);
}
}
class Horse extends Animal {
public constructor(name: string) { super(name); }
public move(distanceInMeters = 45) {
console.log("super name: " + this.name);
console.log("Galloping...");
super.move(distanceInMeters);
}
}
let animal = new Animal("Dog");
animal.move(100);
let horse = new Horse("Horse");
horse.move(200);
[root@angular proj]#
执行和结果确认
[root@angular proj]# gulp
[07:27:38] Using gulpfile /tmp/proj/gulpfile.js
[07:27:38] Starting 'default'...
[07:27:52] Finished 'default' after 14 s
[root@angular proj]# node dist/class-practice.js
Dog moved 100m.
super name: Horse
Galloping...
Horse moved 200m.
[root@angular proj]#
get/set
就像javabean的get和set方法那样,typescript也支持get和set方式,只是写法稍有不同,比如如下一个例子,我们有一个private的成员变量,而对实例进行直接赋值的使用方式则是因为set和get存在的原因。
[root@angular proj]# grep 2 tsconfig.json
"src/class-practice-2.ts"
[root@angular proj]# cat src/class-practice-2.ts
let passcode = "secret passcode";
class Employee {
private _fullName: string;
get fullName(): string {
return this._fullName;
}
set fullName(newName: string) {
if (passcode && passcode == "secret passcode") {
this._fullName = newName;
}
else {
console.log("Error: Unauthorized update of employee!");
}
}
}
let employee = new Employee();
employee.fullName = "Bob Smith";
if (employee.fullName) {
console.log(employee.fullName);
}
[root@angular proj]#
执行和结果确认
[root@angular proj]# gulp
[07:39:42] Using gulpfile /tmp/proj/gulpfile.js
[07:39:42] Starting 'default'...
[07:39:55] Finished 'default' after 13 s
[root@angular proj]# node dist/class-practice-2.js
Bob Smith
[root@angular proj]#
interface
接口方式使用也比较类似,比如如下例子:
[root@angular proj]# cat src/interface-practice.ts
interface LabelledValue {
label: string;
}
function printLabel(labelledObj: LabelledValue) {
console.log(labelledObj.label);
}
let myObj = {size: 10, label: "Size 10 Object"};
printLabel(myObj);
[root@angular proj]#
执行&结果确认
[root@angular proj]# gulp
[07:43:25] Using gulpfile /tmp/proj/gulpfile.js
[07:43:25] Starting 'default'...
[07:43:35] Finished 'default' after 10 s
[root@angular proj]# node dist/interface-practice.js
Size 10 Object
[root@angular proj]#
总结
这篇文章练习和确认了typescript中如何进行面向对象编程方式进行设计和编码。