Class
Basics
Basics
Like Java
Constructor
Constructor
constructor(public publicProperty: type)
- shorthand to declare both parameter and property- child constructor must call super()
- before super() cannot access 'this'
Inheritance
Inheritance
- call parent method
- call instance method call the implementation by instance value, not variable declaration
- super.superMethod()
- 'abstract - like Java
Property Modifiers (static, public, private, protected, readonly)
Property Modifiers (static, public, private, protected, readonly)
- static - like Java
- visibility
- public by default
- private name: string; - a private member, accessible by class but checked for compatibility
- protected - accessible by class and deriving classes
- readonly:
- must be initialized at declaration or in constructor
Accessors
Accessors
(ECMAScript 5+)
- get fullName(): string {...}
- set fullName(newName: string) {..}
Accessors are automatically 'readonly'
Advanced: Constructor Functions (indepth understanding of class/instance/'typeof')
Advanced: Constructor Functions (indepth understanding of class/instance/'typeof')
class T{}:
- T used as value is in fact a constructor function
- as value T can be assigned to other variable
- However T is not a variable therefore cannot be re-assigned
- T used as type (let varT : T) specifies the instances of the class (instanceOfT instanceof T === true)
What 'new' actually do:
- creates a new object ('this')
- sets the prototype of 'this' object to the constructor function's prototype property (note the difference of 'prototype of x' and 'prototype property of x')
- binds the 'this' keyword to the 'this' object and executes the constructor function
- returns the object
'typeof' T (where T is a class):
- used as value, typeof T === 'function'
- used as type, specifies the 'public face' of T
class T {
static staticP = 'p'
tellStaticP() {
console.log(T.staticP)
}
}
// T is in fact a constructor function
console.log(typeof T) // function
// 'typeof' used as value returns a string
console.log(typeof(typeof T)) // string
console.log(typeof T === 'function') // true
// what is an instance of T?
let instanceOfT : T
instanceOfT = new T()
console.log(typeof instanceOfT) // object
console.log(instanceOfT instanceof T) // true
console.log(Object.getPrototypeOf(instanceOfT)) // T{}
console.log(Object.getPrototypeOf(instanceOfT) === T.prototype) // true
console.log(Object.getPrototypeOf(instanceOfT).constructor === T) // true
console.log(Object.getPrototypeOf(instanceOfT).constructor.staticP === T.staticP) // true
console.log(Object.getPrototypeOf(instanceOfT).tellStaticP === instanceOfT.tellStaticP) // true
// let t2: T = T // Compile error: Property 'tellStaticP' is missing in type 'typeof T' but required in type 'T'
// the line above does not work, because 'T' as type means an instance of T, therefore assigning T, the constructor function,
// is an error because the instance of T requires a member function 'tellStaticP' at least in its prototypes
// SUMMARY: 'T' as a type specifies instance of T, with requirements (such as 'tellStaticP') to make a value assignable to 'T'
// SUMMARY: an instance is an object, which's prototype is the 'prototype' property of a function
// SUMMARY: the prototype has a 'constructor' property pointing to the constructor function
// SUMMARY: static member of class is attached to the class (the constructor function)
// SUMMARY: non-static (instance) method is attached to the prototype
console.log("===================================================")
// what is 'typeof T'?
let anotherNameOfSameT: typeof T // here 'typeof' being used as a type, not a value
anotherNameOfSameT = T
console.log(typeof anotherNameOfSameT) // function
console.log(anotherNameOfSameT instanceof T) // false
console.log(Object.getPrototypeOf(anotherNameOfSameT)) // [Function]
console.log(Object.getPrototypeOf(anotherNameOfSameT) === Function.prototype) // true
console.log(anotherNameOfSameT === T) // true
anotherNameOfSameT.staticP = 'new P'
let instanceOfNewT : T = new anotherNameOfSameT()
instanceOfT.tellStaticP() // new P
instanceOfNewT.tellStaticP() // new P
// SUMMARY: typeof T used as a type means the 'constructor function as a type'
// SUMMARY: since a class in typescript is just a constructor function, it can be changed in runtime
console.log("===================================================")
let anotherClassOfT: typeof T
anotherClassOfT = class {
static staticP = 'another P'
tellStaticP() {
console.log("telling from anotherClassOfT, T.staticP: ", T.staticP) // new P
console.log("telling from anotherClassOfT, my own staticP: ", Object.getPrototypeOf(this).constructor.staticP) // another P
}
}
let instanceOfAnotherClassOfT : T = new anotherClassOfT()
instanceOfAnotherClassOfT.tellStaticP()
// SUMMARY: 'typeof T' as a type, is not exactly T (T is T), but type of constructor functions with those type checks
// SUMMARY: here another class can be assigned to a variable of 'typeof T', as long as the class satisfies those checks (required members)
// SUMMARY: so 'typeof T' as a type, is required 'public side signature' of constructor functions
// T = anotherClassOfT // this does not work, T is not a variable
/*
FINAL SUMMARY:
class T{} // T is a constructor function
let typeofT = typeof T // typeof T used as value, is a string, 'function'
let someClass : typeof T // typeof T used as type, is the 'public face' of T,
// so long other constructor function satisfies to this 'public face', it's assignable
*/
Advanced: using a class as an interface
Advanced: using a class as an interface
First needs to understand the constructor function (see above)
Then since class name used as a type specifies the instance type, it can be used as an interface.
class Point {
x: number;
y: number;
}
interface Point3d extends Point {
z: number;
}
let point3d: Point3d = {x: 1, y: 2, z: 3};
Example
Example
class Student {
fullName: string;
constructor(public firstName: string, public middleInitial: string, public lastName: string) {
this.fullName = firstName + " " + middleInitial + " " + lastName;
}
}
class Clock implements ClockInterface {... // implement an interface
// extends
class Dog extends Animal {...
constructor(.....){
.......
super(.....)
// abstract
abstract class Animal {
abstract makeSound(): void;