類
- 引用類的成員時,需要加
this
- 我們使用 new 構造了 Greeter 類的一個例項。 它會呼叫之前定義的建構函式,建立一個 Greeter 型別的新物件,並執行建構函式初始化它。 示例:
class Greeter {
//屬性
greeting: string
//建構函式
constructor(message: string) {
this.greeting = message
}
//方法
greet() {
return "Hello," + this.greeting
}
}
let greeter = new Greeter("world")
複製程式碼
簡單的繼承示例:
class Animal {
move(distanceInMeters: number = 0) {
console.log(`Animal moved ${distanceInMeters}米`)
}
}
class Dog extends Animal {
bark() {
console.log("wang!wang!")
}
}
const dog = new Dog()
dog.bark()
dog.move(10)
複製程式碼
複雜一點得繼承示例:
class Animal {
name: string
constructor(theName: string) {
this.name = theName
}
move(distanceInMeters: number = 0) {
console.log(`${this.name} moved ${distanceInMeters}米`)
}
}
class Snake extends Animal {
// 子類包含一個建構函式,必須呼叫 super(),它會執行基類的建構函式。在構函式訪問this的屬性之前,一定要呼叫super()。這是TypeScript強制執行的一條重要規則。
constructor(name: string) {
super(name)
}
move(distanceInMeters = 45) {
console.log("蛇...")
super.move(distanceInMeters) //訪問類屬性前,需呼叫super,這裡重寫了從基類繼承來的move方法,使得具有不同的功能
}
}
class Horse extends Animal {
constructor(name: string) {
super(name)
}
move(distanceInMeters: number = 35) {
console.log("馬...")
super.move(distanceInMeters)
}
}
let sam = new Snake("sammy the Python")
let tom: Animal = new Horse("Tommy the Palomino")
sam.move()
tom.move(34) //這裡tom宣告使Animal型別,但是值為Horse,呼叫tom.move時,會呼叫Horse裡重寫的方法
//輸出:
// 蛇...
// Sammy the Python moved 5m.
// 馬...
// Tommy the Palomino moved 34m.
複製程式碼
靜態屬性
建立類的靜態成員,這些屬性存在於類本身上面而不是類的例項上。
static
定義靜態屬性,如果要訪問靜態屬性的話,前面必須加上類名(與訪問例項屬性上加this
一樣)
class Grid {
static orgin = { x: 0, y: 0 } // static定義orgin這個靜態屬性
abc:(point:{x:number,y:number}){
//這裡訪問靜態屬性時,在屬性前加上類名的字首
let xDist = (point.x - Grid.origin.x)
let yDist = (point.y - Grid.origin.y)
return Math.sqrt(xDist * xDist + yDist * yDist) / this.scale
}
constructor(public scale: number) //這裡建構函式裡面是定義的例項引數,用到例項屬性的時候,前面是加 this 的字首
}
let grid1 = new Grid(1.0); // 1x scale
let grid2 = new Grid(5.0); // 5x scale
console.log(grid1.abc({x: 10, y: 10}));
console.log(grid2.abc({x: 10, y: 10}));
複製程式碼
抽象類
- 關鍵字
abstract
定義抽象類和在抽象類內部定義抽象方法 - 抽象類中的方法,不包含具體實現,只能在派生類(子類)實現
- 抽象類定義方法和介面類似,只定義方法簽名,不包含具體方法體
- 抽象方法必須包含 abstract 關鍵字並且可以包含訪問修飾符
- 抽象類做為其它派生類的基類使用。 它們一般不會直接被例項化,直接例項化會報錯
abstract class A {
constructor(public name: string) {}
//普通定義方法,包括具體實現,訪問例項屬性用this
printName(): void {
console.log("名字:" + this.name)
}
//抽象類方法,必須有關鍵字 abstract ,並且不包含具體實現,只能在派生類實現
abstract printMeeting(): void
}
//作為抽象類 A 的派生類 B 登場
class B extends A {
constructor() {
//在派生類的建構函式必須呼叫super()
super("LALALALLALA")
}
printMeeting(): void {
console.log("這是基類A定義的抽象類方法,在派生類B的實現")
}
hello(): void {
console.log("這是沒有在基類A定義的方法,只是派生類B定義的普通方法")
}
}
let a: A // 允許建立一個抽象型別的引用
a = new A() //報錯!不能建立一個抽象類的例項,直接例項化報錯
a = new B() // 允許對一個抽象子類進行例項化和賦值
a.printName() //這是抽象類 A裡面定義的普通方法
a.printMeeting() //這是呼叫抽象類 A 裡面定義的抽象類方法
a.hello() //報錯! 這個方法抽象類A中並沒有定義,所以引用報錯
複製程式碼
高階技巧
建構函式
class Greeter {
greeting: string
constructor(message: string) {
this.greeting = message
}
greet() {
return "hello," + this.greeting
}
}
let greeter: Greeter //這樣寫是表明Greeter類的例項的型別是 Greeter
greeter = new Greeter("world")
console.log(greeter.greet())
複製程式碼
把類當做介面使用
類定義會建立兩個東西:類的例項型別和一個建構函式。 因為類可以建立出型別,所以你能夠在允許使用介面的地方使用類。(有點不明白 = =)
class Point {
x: number
y: number
}
interface Point3d extends Point {
z: number
}
let point3d: Point3d = { x: 1, y: 2, z: 3 }
複製程式碼