一隻鴨... 兩隻鴨...
會下蛋的都是好鴨
───────────────────── By Opshell
Class(類別)
在ES6中 JavaScript 終於迎來了 class,
而TypeScript添加了更多的功能給他,
就像前面講的 ES6 + TypeScript,
簡直就是天堂~!!
那
Class(類別)
是甚麼呢?
你可以把他理解成 一張設計圖,或者是生產線,
可以透過定義Class(類別)
來產生特定的物件。
並有著面向物件(OOP)的三大特性:封裝、繼承、多型。
Property(屬性)
存取權讀萬卷書,一樣要行萬里路,
實踐才是學會Codeing的硬道理,
我們直接來個例子講解吧:
class Member {
// Property(屬性)
title: string = 'nobody';
age: number;
protected skill: Array<string> = ['種草', '嘴砲'];
public readonly team = 'Maya';
// constructor(建構子)
constructor(title: string, age: number = 0) {
if (title) { this.title = title; }
this.age = age;
}
// Property(屬性)
public summary(): string {
return `${this.title} is ${this.age} years old.`;
}
}
const Opshell = new Member('Opshell', 30);
const Bear = new Member('Bear');
console.log(Opshell.summary()); // Opshell is 30 years old.
console.log(Bear.summary()); // Bear is 40 years old.
在上面的class中,
我們賦予了他五個Property(屬性)
,
分別是 title、age、skill、summary,
這上面有蠻多東西可以講的:
存取權 | public(公開) |
static(靜態) |
protected(保護) |
private(私有) |
---|---|---|---|---|
誰可以讀取 | Class(類別) 、 Instance(實體) |
Class(類別) 、 Instance(實體) |
自己、繼承Class(類別) 中 |
自己Class(類別) 中 |
呼叫方式 | this | class | this | this |
public(公開)
(如:title、age)。Class(類別)
new 出來的東西,我們稱呼他為Instance(實體)
constructor(建構子)
是 new Instance(實體)
出來時,會執行的區塊,constructor(建構子)
定義。Property(屬性)
在constructor(建構子)
結束前需要給預設值。Property(屬性)
readonly 時,就不能改變,只能讀取。extends(繼承)
上面說了一堆很抽象的東西,
我們來實作一下:
class SuperMember extends Member {
private weight: number;
static skill: Array<string> = [];
constructor(title: string, age: number, weight: number = 100) {
// 在這裡執行的 super 等同於執行父類別的 constructor(建構子)
// 如果要執行其他父類的functionProperty(屬性)`,一樣是透過super:
// super(summary)
super(title, age);
this.weight = weight;
this.skill = this.skill.concat([
'散步投罐罐',
'熊熊掛保證'
]);
}
public DrinkCola(): number {
return this.weight;
}
public superSkill() {
// 這邊this 是指父類(Member)
return this.skill.concat([
'散步投罐罐',
'熊熊掛保證'
]);
}
}
const Bear = new SuperMember('Bear', 40, 110);
console.log(Bear.summary()); // Bear is 40 years old.
console.log(Bear.weight); // 提示:'weight' 是私有屬性,只能從類別 'SuperMember' 中存取
console.log(Bear.DrinkCola()); // 100
console.log(SuperMember.skill); // []
console.log(Bear.superSkill()); // ['種草', '嘴砲', '散步投罐罐', '熊熊掛保證', '散步投罐罐', '熊熊掛保證']
上面的例子可以得出很多結論:
extends(繼承)
出來的新類,可以直接使用父類的Property(屬性)
。private(私有)
屬性 只能在 Class(類別)
使用。static(靜態)
屬性的呼叫,不會執行constructor(建構子)
。protected(保護)
屬性,語法:this.屬性
。※ static function 沒辦法存取父類
protected(保護)
屬性,
因為this會變成自己(子類)本身。
除非父類在回傳時回傳的是this 就能正確識別。
※private(私有)
屬性 子類不能使用外,也不會extends(繼承)
abstract(抽象)
對,我們現在是真的抽象了,
甚麼意思? 比喻一下:Class(類別)
是真的設計圖,
那abstract(抽象)``Class(類別)
就是只是一個設計概念,
設計圖可以直接拿來 new 出Instanceof(實體)
,
但是設計概念沒辦法,他只能拿來extends(繼承)
:
// 新增一個抽象類別,並把team移到 Maya
// 宣告一個抽象發法 getSlogan()
abstract class Maya {
public readonly team = 'Maya';
public abstract getSlogan(): string;
}
然後讓Member繼承Maya:
在Member 裡面補上
public getSlogan = (): string => {
return `${ this.team } ${ this.team } 我的媽呀!`;
};
警告就消失了,在這邊我們可以得到結論:
abstract class(抽象類別)
裡的abstract funciton(抽象方法)
一定要被實現※ 實現時連可見度都需要一樣。
結論都在上面說完啦~~,
如果本身有使用其他語言 php 之類的,
這個章節的內容吸收起來相對會容易很多,
如果沒有,也不是太難懂~~(更難的在後面)~~,
如果有不懂的地方,試著改範例玩玩看,
理解起來會更順暢,
簡單來說:
就是透過Class(類別)
的規範,生成一個Instance(實體)
(也稱實例),
而這個規範是可以透過extends(繼承)
累計的。
而這些規範有四種可見度來決定在那些地方能呼叫、使用。
以上,大家晚安~