Ts Abstract Class
Abstract classes are an important concept in TypeScript object-oriented programming.\n\nThey are classes that cannot be instantiated directly and can only serve as base classes for other classes to inherit from.\n\nAbstract classes are mainly used to define common properties and methods for subclasses, providing a unified structure and behavior template for subclasses.\n\n* * *\n\n* * *\n\n## Why We Need Abstract Classes\n\nIn object-oriented programming, we often need to define some base classes.\n\nThese base classes describe common properties and methods of subclasses, but the implementation details of some methods need to be determined by the subclasses themselves.\n\nAbstract classes are used to solve this problem: they allow us to define method signatures (declarations) while leaving the specific implementation to subclasses.\n\n> **Concept Explanation:** An abstract class is a type between ordinary classes and interfaces. It has characteristics of both interfaces (defining method signatures) and classes (can have concrete method implementations and constructors).\n\n* * *\n\n## Abstract Class Basics\n\nUse the `abstract` keyword to declare abstract classes and abstract methods.\n\nAbstract classes can contain abstract methods and concrete methods (methods with existing implementations).\n\n## Example\n\n// Use the abstract keyword to declare an abstract class\n\n// Abstract classes cannot be instantiated directly, can only serve as base classes\n\nabstract class Animal {\n\n// Animal name property\n\n name: string;\n\n// Constructor\n\n constructor(name: string){\n\nthis.name= name;\n\n}\n\n// Abstract method: modified with abstract, no method body\n\n// Subclasses must implement this method\n\nabstract speak():void;\n\n// Concrete method: method with specific implementation\n\n// Subclasses can inherit and use directly, no need to override\n\n move():void{\n\n console.log(this.name+" is moving");\n\n}\n\n}\n\n// Attempting to instantiate an abstract class will cause an error\n\n// var animal = new Animal("Animal"); // Error: cannot instantiate abstract class\n\n// Define Dog class inheriting from Animal\n\nclass Dog extends Animal {\n\n// Subclass must implement the parent class's abstract method speak()\n\n speak():void{\n\n console.log(this.name+" Woof woof woof!");\n\n}\n\n}\n\n// Create Dog instance\n\nvar dog =new Dog("Wangcai");\n\n dog.speak();// Call method implemented by subclass\n\n dog.move();// Inherit concrete method from parent class\n\n**Output:**\n\nWangcai Woof woof woof!Wangcai is moving\n> **Note:** Abstract methods have no method body (only method signatures), subclasses must implement these methods. Concrete methods have specific implementations, subclasses can inherit and use them directly.\n\n* * *\n\n## Abstract Methods\n\nAbstract methods are methods in abstract classes that are declared but not implemented.\n\nAfter inheriting from an abstract class, subclasses must implement all abstract methods, otherwise an error will occur.\n\n## Example\n\n// Define abstract class Shape (graphic)\n\nabstract class Shape {\n\n// Abstract method: only declaration, no implementation\n\n// Subclasses must implement these two methods\n\nabstract area(): number;\n\nabstract perimeter(): number;\n\n// Concrete method: can use abstract methods\n\n// This method calls abstract methods, subclasses can use normally after inheritance\n\n describe():void{\n\n console.log("Area: "+this.area().toFixed(2));\n\n}\n\n}\n\n// Define Rectangle class inheriting from Shape\n\nclass Rectangle extends Shape {\n\n// Rectangle width\n\n width: number;\n\n// Rectangle height\n\n height: number;\n\n// Constructor\n\n constructor(width: number, height: number){\n\nsuper();// Call parent class constructor\n\nthis.width= width;\n\nthis.height= height;\n\n}\n\n// Implement abstract method: calculate area\n\n area(): number {\n\nreturn this.width*this.height;\n\n}\n\n// Implement abstract method: calculate perimeter\n\n perimeter(): number {\n\nreturn 2*(this.width+this.height);\n\n}\n\n}\n\n// Create rectangle instance\n\nvar rect =new Rectangle(4,5);\n\n// Call inherited describe method, internally calls subclass's area method\n\n rect.describe();\n\n console.log("Perimeter: "+ rect.perimeter());\n\n**Output:**\n\nArea: 20.00Perimeter: 18\n> **Tip:** Concrete methods can call abstract methods. This is because when the concrete method is called, the subclass has already implemented the abstract method, so it can execute normally.\n\n* * *\n\n## Abstract Class as Type\n\nAbstract classes can be used as parameter types.\n\nThis means functions can accept any subclass instance of the abstract class, achieving polymorphism.\n\n## Example\n\n// Define abstract class Animal\n\nabstract class Animal {\n\n// Abstract method: all animals make sounds\n\nabstract speak():void;\n\n}\n\n// Define Cat class inheriting from Animal\n\nclass Cat extends Animal {\n\n// Implement abstract method\n\n speak():void{\n\n console.log("Meow meow meow!");\n\n}\n\n}\n\n// Define Dog class inheriting from Animal\n\nclass Dog extends Animal {\n\n// Implement abstract method\n\n speak():void{\n\n console.log("Woof woof woof!");\n\n}\n\n}\n\n// Define function parameter type as abstract class Animal\n\n// This function can accept any subclass instance of Animal\n\nfunction makeSpeak(animal: Animal):void{\n\n animal.speak();\n\n}\n\n// Pass different subclass instances to achieve different behaviors (polymorphism)\n\n makeSpeak(new Cat());\n\n makeSpeak(new Dog());\n\n// Abstract class type array: can store different subclass instances\n\nvar animals: Animal[]=[new Cat(),new Dog()];\n\n**Output:**\n\nMeow meow meow!Woof woof woof!\n> **Polymorphism:** When an abstract class is used as a type, the actual execution is the subclass's method implementation. This is the polymorphism feature of object-oriented programming.\n\n* * *\n\n## Difference Between Abstract Classes and Interfaces\n\nBoth abstract classes and interfaces are used to define type specifications, but there are some key differences.\n\nUnderstanding their differences helps make the right choice in actual development.\n\n| Feature | Abstract Class | Interface |\n| --- | --- | --- |\n| Instantiation | Cannot be instantiated directly | Cannot be instantiated directly |\n| Method Implementation | Can have concrete implementation | Can only have declarations (TypeScript 3.6+ can have default implementations) |\n| Member Modifiers | Can add public, protected, private | Can only have readonly |\n| Inheritance | Single inheritance (can only extends one class) | Multiple implementation (can implements multiple interfaces) |\n| Constructor | Can have constructor | Cannot have constructor |\n\n> **Selection Advice:** Use abstract classes when code sharing is needed; use interfaces when only defining specifications/contracts is needed; use interfaces when multiple inheritance is needed.\n\n* * *\n\n## Complete Example: Payment System\n\nBelow is a payment system example implemented using abstract classes.\n\nThis example demonstrates the application of abstract classes in actual projects.\n\n## Example\n\n// Define abstract payment class\n\nabstract class Payment {\n\n// Abstract method: process payment, subclasses must implement\n\nabstract process(amount: number):boolean;\n\n// Concrete method: validate payment information\n\n// All subclasses can use this method\n\n validate():void{\n\n console.log("Verify payment information");\n\n}\n\n}\n\n// Credit card payment class\n\nclass CreditCardPayment extends Payment {\n\n// Credit card number\n\n cardNumber: string;\n\n// Constructor\n\n constructor(cardNumber: string){\n\nsuper();// Call parent class constructor\n\nthis.cardNumber= cardNumber;\n\n}\n\n// Implement abstract method: process credit card payment\n\n process(amount: number):boolean{\n\n console.log("Process credit card payment: "+ amount);\n\nreturn true;\n\n}\n\n}\n\n// PayPal payment class\n\nclass PayPalPayment extends Payment {\n\n// PayPal email\n\n email: string;\n\n// Constructor\n\n constructor(email: string){\n\nsuper();\n\nthis.email= email;\n\n}\n\n// Implement abstract method: process PayPal payment\n\n process(amount: number):boolean{\n\n console.log("Process PayPal payment: "+ amount);\n\nreturn true;\n\n}\n\n}\n\n// Use polymorphism to handle different payment methods\n\nvar payments: Payment[]=[\n\nnew CreditCardPayment("1234"),\n\nnew PayPalPayment("test@example.com")\n\n];\n\n// Iterate through each payment method\n\nfor(var _i =0, payments_1 = payments; _i < payments_1.length; _i++){\n\nvar payment = payments_1;\n\n// Call inherited validation method\n\n payment.validate();\n\n// Call subclass's processing method\n\n payment.process(100);\n\n}\n\n**Output:**\n\nVerify payment information: Process credit card payment: 100Verify payment information: Process PayPal payment: 100\n> **Application Scenarios:** Abstract classes are commonly used in framework design and business logic layering. Examples include payment processing, user authentication, data persistence, and other scenarios.\n\n* * *\n\n## Notes\n\n* **Cannot instantiate:** Abstract classes cannot be created directly using new, must be inherited through subclasses\n* **Must implement abstract methods:** Subclasses will error if they don't implement all abstract methods\n* **Can have constructor:** Abstract classes can define constructors, subclasses need to call super()\n* **Single inheritance:** A class can only inherit one abstract class (single inheritance)\n* **Access modifiers:** Abstract methods can use public, protected modifiers\n\n> **Best Practice:** Use abstract classes when multiple classes need to share code and logic. Use interfaces when only defining specifications and contracts is needed.\n\n* * *\n\n## Summary\n\nAbstract classes are an important part of TypeScript object-oriented programming.\n\n* **abstract keyword:** Used to declare abstract classes and methods\n* **Cannot instantiate:** Can only be used through subclass inheritance\n* **Abstract methods:** Methods that subclasses must implement\n* **Concrete methods:** Methods with implementation that subclasses can inherit and use directly\n* **Template method pattern:** Abstract class defines the skeleton, subclasses provide concrete implementation\n\n> **Suggestion:** When designing class hierarchies, prioritize using abstract classes to share code and define specifications.
YouTip