From 7aa8a034c77ba61688fc2a74a63634ccc7485d72 Mon Sep 17 00:00:00 2001 From: tactonbishop Date: Tue, 20 Sep 2022 14:30:05 +0100 Subject: [PATCH] Last Sync: 2022-09-20 14:30:05 --- Programming_Languages/TypeScript/Classes.md | 88 +++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/Programming_Languages/TypeScript/Classes.md b/Programming_Languages/TypeScript/Classes.md index b332d26..c23c4d7 100644 --- a/Programming_Languages/TypeScript/Classes.md +++ b/Programming_Languages/TypeScript/Classes.md @@ -120,4 +120,92 @@ class Programmer implements Person { ## Inheritance +We can extend classes in TypeScript by using sub-classes or abstract classes. + +### Sub-classes + +In the case of sub-classes, we use the phrase `[child_class] extends [parent_class]` in the class declaration to designate the inheritance relationship between the base class and the new class that is derived from it. + +> A derived class has all the properies and methods of its base class but can also define additional members. + +When you instantiate a child class from a parent class, if the parent class has constructor values, you must initialise these in the child. You do this by calling the parent constructor via the `super()` syntax. For example: + +```ts +class Employee extends Person { + constructor(firstName: string, lastName: string, private jobTitle: string) { + // call the constructor of the Person class: + super(firstName, lastName); + } +} +``` + +To override or alter a method that exists on the parent in the child, you can use the syntax `super.[methodName]()`. + +### Abstract classes + +Classes marked `abstract` are similar to parent in the case of sub-classes. The difference is that they are like templates. Several of their methods and properties may be directly inherited by classes that derive from them (just like sub-classes) but they can include 'blank' methods and properties that are placeholders for methods and properties that are defined in the derivation class. + +I have found this useful for cases where you want to inherit methods from a parent class but implement a specific method differently in each derivation. + +```ts +export abstract class IndexHyperlinksProvider + implements vscode.TreeDataProvider +{ + public activeFile: string | undefined + private outlinks + private fileSystemUtils: FileSystemUtils + + constructor( + activeFile: string | undefined, + workspaceRoot: string | undefined + ) { + this.setActiveFile(activeFile) + this.outlinks = this.generateLinks() + this.fileSystemUtils = new FileSystemUtils(workspaceRoot) + } + + abstract generateLinks(): Promise + + public setActiveFile(activeFile: string | undefined) { + this.activeFile = activeFile + } + ... +``` + +Above we have a base class with a single abstract method `generateLinks()`. The class below extends this base. Note that it passes the parent constructor values to `super` and defines an actual method for the designated `generateLinks()` template: + +```ts +export class IndexOutlinksProvider extends IndexHyperlinksProvider { + public workspaceFiles: string[]; + public context: vscode.ExtensionContext; + constructor( + activeFile: string | undefined, + workspaceRoot: string | undefined, + workspaceFiles: string[], + context: vscode.ExtensionContext + ) { + super(activeFile, workspaceRoot); + this.workspaceFiles = workspaceFiles; + this.context = context; + } + + public async generateLinks(): Promise { + const indexer = new IndexHyperlinks(this.context, this.workspaceFiles); + if (typeof this.activeFile === "string") { + const outlinks = await indexer.indexOutlinks(this.activeFile); + if (outlinks !== undefined) { + return this.transformLinksToTreeItem(outlinks); + } + } + return; + } +} +``` + +> Importantly, you cannot instantiate abstract classes. You can only `extend` them and then instantiate their derivation. This is another important difference from sub-classes. + +As with sub-classes, you must initialise the properties of the parent constructor with `super`. + ### `implements` vs `extends` + +You shouldn't confuse `implements` with `extends`. `implements` just checks the class as an interface in accordance with the principles of [duck typing](/Programming_Languages/TypeScript/Custom_types.md#duck-typing): i.e the implementing class should have the same properties and methods. It doesn't affect anything internal to the methods or properties. So e.g, if you typed a method parameter as `string` in the base class, this would still default to `any` in the derived class.