TypeScript 类

TypeScript 类

TypeScript 是面向对象的 JavaScriptTypeScript 支持类、接口等面向对象编程的特性。在面向对象编程中,类是用于创建对象的蓝图。类封装了对象的数据。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()

编译后,会生成以下JavaScript代码。

//Generated by typescript 1.8.10
var Car = (function () {
   //constructor
   function Car(engine) {
      this.engine = engine;
   }

   //function
   Car.prototype.disp = function () {
      console.log("Function displays Engine is  :   " + this.engine);
   };
   return Car;
}());

//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()

在编译时,它将生成以下JavaScript代码。

//Generated by typescript 1.8.10
var __extends = (this && this.__extends) || function (d, b) {
   for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
   function __() { this.constructor = d; }
   d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var Shape = (function () {
   function Shape(a) {
      this.Area = a;
   }
   return Shape;
}());

var Circle = (function (_super) {
   __extends(Circle, _super);
   function Circle() {
      _super.apply(this, arguments);
   }

   Circle.prototype.disp = function () { 
      console.log("Area of the circle:  " + this.Area); 
   };
   return Circle;
}(Shape));

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类的属性。

编译后,将生成以下JavaScript代码。

//Generated by typescript 1.8.10
var __extends = (this && this.__extends) || function (d, b) {
   for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
   function __() { this.constructor = d; }
   d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};

var Root = (function () {
   function Root() {
   }
   return Root;
}());

var Child = (function (_super) {
   __extends(Child, _super);
   function Child() {
      _super.apply(this, arguments);
   }
   return Child;
}(Root));

var Leaf = (function (_super) {
   __extends(Leaf, _super);
   function Leaf() {
      _super.apply(this, arguments);
   }
   return Leaf;
}(Child));

var obj = new Leaf();
obj.str = "hello";
console.log(obj.str);

它的输出如下:

输出

hello

TypeScript ─ 类继承和方法重写

方法重写是子类重新定义了父类的方法的机制。下面的示例说明了这一点 –

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()函数的超类版本。

编译时,它将生成以下JavaScript代码。

//Generated by typescript 1.8.10
var __extends = (this && this.__extends) || function (d, b) {
   for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
   function __() { this.constructor = d; }
   d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};

var PrinterClass = (function () {
   function PrinterClass() {
   }
   PrinterClass.prototype.doPrint = function () { 
      console.log("doPrint() from Parent called…"); 
   };
   return PrinterClass;
}());

var StringPrinter = (function (_super) {
   __extends(StringPrinter, _super);

   function StringPrinter() {
      _super.apply(this, arguments);
   }

   StringPrinter.prototype.doPrint = function () {
      _super.prototype.doPrint.call(this);
      console.log("doPrint() is printing a string…");
   };

   return StringPrinter;
}(PrinterClass));

var obj = new StringPrinter();
obj.doPrint();

以上代码的输出如下 –

doPrint() from Parent called… 
doPrint() is printing a string…

静态关键字

静态关键字可以应用于类的数据成员。静态变量在程序执行完成前保留其值。静态成员通过类名引用。

示例

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

编译后,将生成以下JavaScript代码。

//Generated by typescript 1.8.10
var StaticMem = (function () {
   function StaticMem() {
   }

   StaticMem.disp = function () {
      console.log("The value of num is" + StaticMem.num);
   };

   return StaticMem;
}());

StaticMem.num = 12;     // initialize the static variable
StaticMem.disp();      // invoke the static method

上面代码的输出如下所示:

The value of num is 12

实例运算符

实例运算符返回true,如果对象属于指定的类型。

示例

class Person{ } 
var obj = new Person() 
var isPerson = obj instanceof Person; 
console.log(" obj is an instance of Person " + isPerson);

在编译时,它将生成以下JavaScript代码。

//Generated by typescript 1.8.10
var Person = (function () {
   function Person() {
   }
   return 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

数据隐藏

一个类可以控制其数据成员对其他类成员的可见性。这种能力被称为数据隐藏或封装。

面向对象使用访问修饰符或访问说明符的概念来实现封装的概念。访问修饰符/说明符定义了一个类在其定义类之外的数据成员的可见性。

TypeScript支持的访问修饰符有:

序号 访问指定符&描述
1. 公共的 公共数据成员具有普遍的可访问性。类中的数据成员默认为公共的。
2. 私有的 私有数据成员只能在定义这些成员的类内部访问。如果外部类成员尝试访问私有成员,编译器会抛出错误。
3. 受保护的 受保护的数据成员可被该成员所属类及其子类的成员访问。

示例

现在让我们通过一个示例来看看数据隐藏是如何工作的−

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,分别是公有和私有成员。该类被实例化。在示例中,当以声明它的类之外的方式访问私有属性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 作为其成员之一。

在编译过程中,将生成以下的 JavaScript 代码。

//Generated by typescript 1.8.10
var AgriLoan = (function () {
   function AgriLoan(interest, rebate) {
      this.interest = interest;
      this.rebate = rebate;
   }
   return AgriLoan;
}());

var obj = new AgriLoan(10, 1);
console.log("Interest is : " + obj.interest + " Rebate is : " + obj.rebate);

上述代码的输出结果如下:

Interest is : 10 Rebate is : 1

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程