TypeScript是面向对象的JavaScript。TypeScript支持面向对象的编程功能,如类,接口等。OOP中的类是用于创建对象的蓝图。类封装了对象的数据。Typescript为这个名为类的概念提供内置支持。JavaScript ES5或更早版本不支持类。TypeScript会从ES6获得此功能。
一、类的创建
使用class关键字的TypeScript声明一个类。语法如下所示:
语法
class class_name {
//class scope
}
class关键字后跟类名。在命名类时必须考虑标识符的规则。
一个类定义可以包括以下内容:
-
字段 - 字段是在类中声明的任何变量。字段表示与对象有关的数据
-
构造函数 - 负责为类的对象分配内存
-
函数 - 函数表示对象可以采取的操作。它们有时也被称为方法。
这些组件放在一起称为该类的数据成员
考虑TypeScript中的Person类。
class Person {
}
在编译时,它会生成以下JavaScript代码:
//Generated by typescript 1.8.10
var Person = (function () {
function Person() {
}
return Person;
}());
例如:声明一个类
class Car {
//field
engine:string;
//constructor
constructor(engine:string) {
this.engine = engine
}
//function
disp():void {
console.log("Engine is : "+this.engine)
}
}
本示例声明一个类Car。该类有一个名为engine的字段。同时,声明字段时不使用var关键字。上面的例子声明为类的构造函数。
构造函数是类的特殊函数,负责初始化类的变量。TypeScript使用constructor关键字定义构造函数。构造函数是一个函数,因此可以参数化。
this关键字是引用类的当前实例。这里,参数名称和类字段的名称是相同的。因此,为了避免歧义,类的字段以this关键字为前缀。
disp()是一个简单的函数定义。注意,此处不使用function关键字。
在编译时,它会生成以下JavaScript代码:
//Generated by typescript 1.8.10
var Car = (function () {
//constructor
function Car(engine) {
this.engine = engine;
}
//function
Car.prototype.disp = function () {
console.log("Engine is : " + this.engine);
};
return Car;
}());
二、创建实例对象
要创建类的实例,请使用new关键字后跟类名。语法如下所示:
语法
var object_name = new class_name([ arguments ])
-
new关键字负责实例化。
-
表达式的右边调用构造函数。如果参数化,构造函数应该传递值。
例如:实例化一个类
var obj = new Car("Engine 1")
三、访问属性和函数
可以通过对象访问类的属性和函数。使用“.”点表示法(称为句点)访问类的数据成员。
//accessing an attribute
obj.field_name
//accessing a function
obj.function_name()
示例:将它们放在一起
class Car {
//field
engine:string;
//constructor
constructor(engine:string) {
this.engine = engine
}
//function
disp():void {
console.log("Function displays Engine is : "+this.engine)
}
}
//create an object
var obj = new Car("XXSY1")
//access the field
console.log("Reading attribute value Engine as : "+obj.engine)
//access the function
obj.disp()
上面的代码的输出如下:
Reading attribute value Engine as : XXSY1
Function displays Engine is : XXSY1
四、类继承
TypeScript支持继承的概念。继承是一种程序从现有的类中创建新类的能力。扩展为创建较新类的类称为父类/超类。新创建的类被称为子类。
一个类使用“extends”关键字从另一个类继承。子类继承父类的私有成员和构造函数之外的所有属性和方法。
语法
class child_class_name extends parent_class_name
然而,TypeScript不支持多重继承。
示例:类继承
class Shape {
Area:number
constructor(a:number) {
this.Area = a
}
}
class Circle extends Shape {
disp():void {
console.log("Area of the circle: "+this.Area)
}
}
var obj = new Circle(223);
obj.disp()
上面的代码的输出如下:
Area of the Circle: 223
上面的例子声明了一个类Shape。该类由Circle类扩展。既然是类之间的继承关系,因此子类(即Car类)获得对其父类属性(即area)的隐式访问。
继承可以归类为:
-
单个 - 每个类最多可以从一个父类扩展
-
多个 - 一个类可以从多个类继承。TypeScript不支持多重继承。
-
多级的 - 下面的例子显示多级继承的工作原理。
示例
class Root {
str:string;
}
class Child extends Root {}
class Leaf extends Child {} //indirectly inherits from Root by virtue of inheritance
var obj = new Leaf();
obj.str ="hello"
console.log(obj.str)
类Leaf通过多级继承从Root类和Child类派生属性。
它的输出如下:
hello
五、类的继承和方法重写
方法重写是由子类重新定义父类方法的机制。 以下示例说明了相同的情况:
class PrinterClass {
doPrint():void {
console.log("doPrint() from Parent called…")
}
}
class StringPrinter extends PrinterClass {
doPrint():void {
super.doPrint()
console.log("doPrint() is printing a string…")
}
}
var obj = new StringPrinter()
obj.doPrint()
super关键字用来引用类的直接父级。关键字可用于引用变量,属性或方法的超类版本。第13行调用的doWork()函数的超类版本。
上面的代码的输出如下:
doPrint() from Parent called…
doPrint() is printing a string…
六、static关键字
static关键字可以应用于类的数据成员。静态变量保留其值,直到程序完成执行。静态成员由类名引用。
示例
class StaticMem {
static num:number;
static disp():void {
console.log("The value of num is"+ StaticMem.num)
}
}
StaticMem.num = 12 // initialize the static variable
StaticMem.disp() // invoke the static method
上面的代码的输出如下:
The value of num is 12
七、instanceof运算符
如果对象属于指定类型,则instanceof运算符返回true。
示例
class Person{ }
var obj = new Person()
var isPerson = obj instanceof Person;
console.log(" obj is an instance of Person " + isPerson);
上面的代码的输出如下:
obj is an instance of Person True
八、数据隐藏
类可以控制其数据成员的其他类成员的可见性。此功能称为Data Hiding(数据隐藏
)或Encapsulation(封装)。
面向对象使用访问修饰符或访问说明符的概念来实现封装的概念。访问说明符/修饰符定义类的数据成员在其定义类之外的可见性。
通过TypeScript支持的访问修饰符是 -
序号 | 访问说明符和说明 |
---|---|
1 | public 公共的数据成员具有普遍的可访问性。默认情况下,类中的数据成员是公共的。 |
2 | private 私有数据成员只能在定义这些成员的类中访问。如果外部类成员尝试访问私有成员,则编译器会引发错误。 |
3 | protected 受保护的数据成员可以由与前者相同的类中的成员访问,也可以由子类的成员访问。 |
示例
现在让我们举个例子来看看数据隐藏如何工作:
class Encapsulate {
str:string = "hello"
private str2:string = "world"
}
var obj = new Encapsulate()
console.log(obj.str) //accessible
console.log(obj.str2) //compilation Error as str2 is private
该类有两个字符串属性,str1和str2,分别是public和private成员。该类被实例化。该示例返回一个编译时错误,因为私有属性str2在声明它的类之外访问。
九、类和接口
类还可以实现接口。
interface ILoan {
interest:number
}
class AgriLoan implements ILoan {
interest:number
rebate:number
constructor(interest:number,rebate:number) {
this.interest = interest
this.rebate = rebate
}
}
var obj = new AgriLoan(10,1)
console.log("Interest is : "+obj.interest+" Rebate is : "+obj.rebate )
AgriLoan类实现了Loan接口。因此,它现在绑定在类上以包含interest属性作为其成员。
上面的代码的输出如下:
Interest is : 10 Rebate is : 1