如何在 TypeScript 中创建抽象类?

typescriptserver side programmingprogramming

抽象简介

我们希望读者在实现抽象类之前熟悉抽象类及其要求。抽象意味着隐藏。它用于向用户和一些开发人员隐藏底层代码实现。此外,它用于仅显示有关方法的必需信息,而不是显示方法的整个复杂实现。

创建抽象类

我们可以使用 abstract 关键字来定义抽象类或方法。抽象类可以包含普通和抽象类型的方法。在抽象类中,我们需要实现功能性或普通方法,并且只需声明抽象方法。

我们可以使用任何其他类继承抽象类,但我们需要将抽象类的所有抽象方法实现到继承的类中。如果我们不想在继承类中实现抽象方法,则需要使用 abstract 关键字将继承类抽象化。

此外,我们不能创建抽象类的对象,但我们可以创建继承类的对象并使用抽象类方法。抽象类的局限性在于我们不能使用多个抽象类实现多重继承。

语法

用户可以按照以下语法创建抽象类并将其继承到其他类。

abstract class sample {
   // 在抽象类中定义变量,
   // 在抽象类中声明抽象方法或非抽象方法
   abstract demo(string): void;
}
// 扩展sample类,并将sample的所有抽象方法实现到demo类中
class test extends sample {
   demo(name: string): void {
      // 演示方法的代码
   }
}

步骤

  • 步骤 1 − 定义名为 sample 的抽象类,其中包含名为 property1 和 property2 的属性。

  • 步骤 2 − 另外,在 sample 类中添加构造函数以初始化 property1 和 property2 的值​​。

  • 步骤 3 − 在抽象类中声明抽象方法名称 demo()。此外,定义抽象类的 save() 方法,这是一个非抽象方法,用于打印 property1 和 property2 的值​​。

  • 步骤 4 − 定义测试类,这是一个继承 sample 类的非抽象类。另外,将字符串类型的 property3 添加到测试类中。

  • 步骤 5 - 将构造函数添加到测试类中,该构造函数需要 3 个参数,并使用前 2 个参数调用超类(即示例类)的构造函数。

  • 步骤 6 - 在测试类中实现示例类的 demo() 方法,该方法打印 property3 的值。

示例 1

在下面的示例中,我们定义了包含抽象方法的抽象类。在继承的测试类中,我们实现了示例类的抽象方法。接下来,我们创建了具有 3 个参数的测试类的对象,并使用它来调用 demo() 和 save() 方法。

abstract class sample {
   // 在抽象类中定义变量,
   property1: string;
   constructor(property1: string, property2: number) {
      this.property1 = property1;
   }
   // 声明抽象方法
   abstract demo(): void;
   
   // 定义非抽象方法
   save(): void {
      console.log("The save method of the abstract class is executed.");
   }
}
// 扩展sample类,并将sample的所有抽象方法实现到demo类中
class test extends sample {
   property2: number;
   constructor(property1: string, property2: number) {
      super(property1);
      this.property2 = property2;
   }
   demo(): void {
      // 演示方法的代码
      console.log("The value of the property 3 is " + this.propert2);
   }
}
let test_obj = new test("TutorialsPont", 9999);
test_obj.demo();
test_obj.save();

在上面的示例中,我们从继承的类测试中隐藏了 save() 方法的实现。我们允许开发人员根据需要实现 demo() 方法,但隐藏其他类信息,例如 property1、property2 和 save() 方法的实现。

现在,用户正确理解了使用抽象类的动机以及我们如何使用它来隐藏信息并仅显示所需的信息。

在编译时,上述代码将生成以下 JavaScript 代码 -

var __extends = (this && this.__extends) || (function () {
   var extendStatics = function (d, b) {
      extendStatics = Object.setPrototypeOf ||
      ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
      function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
      return extendStatics(d, b);
   };
   return function (d, b) {
      extendStatics(d, b);
      function __() { this.constructor = d; 
   }
   d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var sample = /** @class */ (function () {
   function sample(property1, property2) {
      this.property1 = property1;
   }
   // 定义非抽象方法
   sample.prototype.save = function () {
      console.log("The save method of the abstract class is executed.");
   };
   return sample;
}());
// 扩展sample类,并将sample的所有抽象方法实现到demo类中
var test = /** @class */ (function (_super) {
   __extends(test, _super);
   function test(property1, property2) {
      var _this = _super.call(this, property1) || this;
      _this.property2 = property2;
      return _this;
   }
   test.prototype.demo = function () {
      // 演示方法的代码
      console.log("The value of the property 3 is " + this.propert2);
   };
   return test;
}(sample));
var test_obj = new test("TutorialsPont", 9999);
test_obj.demo();
test_obj.save();

输出

它将产生以下输出 -

The value of the property 3 is undefined
The save method of the abstract class is executed.

示例 2

在下面的例子中,class1是抽象类,它包含抽象方法名method1的声明。class2只包含method2()的定义。它扩展了class1,但没有实现名为method1()的抽象方法。

之后,我们定义了class3,并通过class2继承了它。此外,我们在class3中定义了类的method1。最后,我们创建了class3的对象并调用了method1()和method2()。

// 定义包含抽象method1的抽象类
abstract class class1 {
    abstract method1(): void;
}
// 需要创建class2来抽象,因为我们继承了class1,但没有定义抽象method1()
abstract class class2 extends class1 {
   method2(): void {
      console.log("Inside the method 2 of class2.");
   }
}
// 定义由 class2 继承的 class3
class class3 extends class2 {
    // 实现抽象类 1 的 method1
    method1(): void {
        console.log(
             "Implemented the abstract method name method1 of class1 inside the class3"
        );
    }
}
// 创建 class3 的对象
var object = new class3();

// 调用在抽象类 1 中声明的 class1 的 method1
object.method1();

// 调用 class2 的 method2
object.method2();

上面的例子告诉我们,如果我们通过任何类继承抽象类,并且不想在继承的类中实现抽象方法,我们需要使继承的类抽象化。

在编译时,上面的代码将生成以下 JavaScript 代码 −

var __extends = (this && this.__extends) || (function () {
   var extendStatics = function (d, b) {
      extendStatics = Object.setPrototypeOf ||
         ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
         function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
         return extendStatics(d, b);
      };
      return function (d, b) {
         extendStatics(d, b);
         function __() { this.constructor = d; }
         d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
      };
})();
// 定义包含抽象方法1的抽象类1
var class1 = /** @class */ (function () {
   function class1() {
   
   }
   return class1;
}());
// 需要创建 class2 来抽象,因为我们继承了 class1,但没有定义抽象方法 1()
var class2 = /** @class */ (function (_super) {
   __extends(class2, _super);
   function class2() {
      return _super !== null && _super.apply(this, arguments) || this;
   }
   class2.prototype.method2 = function () {
      console.log("Inside the method 2 of class2.");
   };
   return class2;
}(class1));
// 定义类 3 被类 2 继承
var class3 = /** @class */ (function (_super) {
   __extends(class3, _super);
   function class3() {
   return _super !== null && _super.apply(this, arguments) || this;
   }
   // 抽象类1的方法1的实现
   class3.prototype.method1 = function () {
      console.log("Implemented the abstract method name method1 of class1 inside the class3");
   };
   return class3;
}(class2));
// 创建 class3 的对象
var object = new class3();

// 调用 class1 中声明的抽象 class1 的方法 1
object.method1();

// 调用 class2 的方法 2
object.method2();

输出

它将产生以下输出 -

Implemented the abstract method name method1 of class1 inside the class3
Inside the method 2 of class2.

用户在本教程中学习了如何实现抽象类。现在,用户可以理解我们如何使用抽象类和抽象方法隐藏类的其他信息。

此外,用户可以使用接口进行抽象。接口的所有方法在 TypeScript 中都是抽象的,并且不允许非抽象方法。此外,我们可以使用该接口进行多重继承。


相关文章