Comparing classes

Classes are different than interfaces, types, or primitives. They have a prototype chain and obey different rules. For example, two different classes can be interchangeable if they have the same structure. The following classes, C1 and C2, are identical in terms of structure and can be swapped in the function that requires C1. You can even instantiate C2 in a C1 variable:

class C1 {
public a: number = 1;
public funct(): void { }
}

class C2 {
public a: number = 1;
public funct(): void { }
}

const c1: C1 = new C1();
const c2: C2 = new C2();
const c12: C1 = new C2();

function executeClass1(c1: C1): void {
c1.funct();
}

executeClass1(c1);
executeClass1(c2);
executeClass1(c12);

If we add in the private field in C1 or C2, then it won't be the same:

class C1 {
public a: number = 1;
public funct(): void { }
private p: string = "p";
}

class C2 {
public a: number = 1;
public funct(): void { }
private p: string = "p";
}

const c1: C1 = new C1();
const c2: C2 = new C2();
const c12: C1 = new C2(); // Does not compile

function executeClass1(c1: C1): void {
c1.funct();
}

executeClass1(c1);
executeClass1(c2); // Does not compile
executeClass1(c12);

The private and protected fields make each class unique. TypeScript continues to compare the structure but does make an exception with regard to these two visibility modifiers.

The reason is when using inheritance and assigning a child class to a base type it must be from the same hierarchy and not something with a similar shape that is not from the same hierarchy. The following code shows how without a private or a protected field the base class can be substituted by a single class that has the structure of the child and the base:

class B1 {
public baseFunct(): void { }
}

class C1 extends B1 {
public a: number = 1;
public funct(): void { }
}

class C2 {
public a: number = 1;
public funct(): void { }
public baseFunct(): void { }
}

const c1: B1 = new C1();
const c2: B1 = new C2();

However, adding a private field at the base class B1 and the same in C2 makes them different, which stops C2 being addressable to the variable C2 of type B1:

class B1 {
private name: string = "b1";
public baseFunct(): void { }
}

class C1 extends B1 {
public a: number = 1;
public funct(): void { }
}

class C2 {
private name: string = "c2";
public a: number = 1;
public funct(): void { }
public baseFunct(): void { }
}

const c1: B1 = new C1();
const c2: B1 = new C2(); // Does not compile

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.12.136.63