TypeScript の 類 介面
阿新 • • 發佈:2020-11-22
建立一個物件
class Person{
public name:string;
public age:number;
constructor(name:string, age:number){
this.name = name;
this.age = age;
}
}
let a = new Person("測試", 15);
console.log(a.name + " --- " + a.age)
繼承
class NewPerson extends Person{ public sex: number; constructor(sex: number){ this.sex = sex; } }
由圖可見,上面的繼承是不正常的,所以這裡需要呼叫其super方法
class NewPerson extends Person{
public sex: number;
constructor(name:string,age:number,sex: number){
super(name,age);
this.sex = sex;
}
}
私有屬性
class PrivatePerson{ private name:string; constructor(name:string){ this.name = name; } } let c = new PrivatePerson("wz"); console.log(c.name) // 提示報錯
這個就是私有屬性,那麼我們該怎麼訪問這個私有屬性呢?
class PrivatePerson{
private name:string;
constructor(name:string){
this.name = name;
}
get getName(){
return this.name;
}
}
let c = new PrivatePerson("wz");
console.log(c.getName)
通過上述的
get
修飾的屬性(看起來更像一個方法),便可以獲取到私有屬性,最後可以通過c.getName
獲取到
有get
獲取屬性,那麼是否有set
設定屬性呢???
class PrivatePerson{
private name:string;
constructor(name:string){
this.name = name;
}
get getName(){
return this.name;
}
set setName(name: string){
this.name = name
}
}
let c = new PrivatePerson("wz");
console.log(c.getName)
c.setName = "哈哈";
console.log(c.getName)
通過上面
set
的案例,我們應該清楚的看到,其實get
和set
修飾的都不是方法,而是屬性,因為方法的呼叫fn()
,而這個看起來更像是屬性的寫法,所以這裡注意c.setName = "哈哈"
,既然這樣,為了美觀,我們將上面的進行一個修改
class PrivatePerson{
private _name:string;
constructor(name:string){
this._name = name;
}
get name(){
return this._name;
}
set name(name: string){
this._name = name
}
}
let c = new PrivatePerson("wz");
console.log(c.name)
c.name = "哈哈";
console.log(c.name)
這樣看起來就完全一樣了
私有屬性作用是什麼呢?
實現單例模式
class SimpleObject {
//靜態方法中只能呼叫靜態變數
private static simpleInfo: SimpleObject;
//私有化建構函式,讓其無法被外界`new`出來
private constructor(){}
//提供公共的靜態的獲取例項方法
public static getInstance(){
//判斷例項是否存在
if(!this.simpleInfo){
//不存在就例項化一個
this.simpleInfo = new SimpleObject();
}
//返回例項
return this.simpleInfo;
}
}
以上的單例模式很簡單,但是也需要注意幾個小點
- 因為我們需要實現"單例模式",所以必須要限制例項化的方式,只能由我們內部提供,所以將
建構函式私有化
,在前面加上private
- 獲取例項方法: 因為我們把建構函式
constructor
私有化了,所以外部無法使用new
關鍵字例項化物件,我們必須要提供的獲取例項方法getInstance
必須可以在不例項化的情況下呼叫,所以這個方法必須使用static
修飾 - 靜態方法只能訪問靜態的資料,所以這裡的例項
simpleInfo
也是靜態的,並且為了不讓其被外部直接呼叫,所以加上private
實現部分屬性只能獲取,而無法修改
- 私有屬性實現
class PriPerson{
private _name:string;
constructor(name :string){
this._name = name;
}
get name(){
return this._name
}
}
let e = new PriPerson("一個人");
console.log(e.name)
e.name = "不可修改" //報錯
- readonly實現
class PriPerson{
public readonly name:string;
constructor(name :string){
this.name = name;
}
}
let e = new PriPerson("一個人");
console.log(e.name)
e.name = "不可修改" //報錯
抽象類
有時候需要分類,同一類事物有著公共的特性,公共的方法(但是每個之間實現不同),這個時候我們就可以定義個抽象類,抽出相同的,相同的方法
abstract class Animal{
getEatOrgan(){
return "嘴";
}
abstract eat():string;
}
class People extends Animal{
eat(){
return "使用手抓吃飯";
}
}
class Pig extends Animal{
eat(){
return "使用嘴拱著吃";
}
}
let animals : [string, string] = ["man", "pig"];
animals.forEach((animal) => {
let unknownAnimal:Animal;
unknownAnimal = animal === "man" ? new People() : new Pig();
console.log("吃飯通用器官:" + unknownAnimal.getEatOrgan(),
"各自吃飯方式: " + unknownAnimal.eat());
})
結果
介面的繼承
我們常常會定義一些介面,用於型別定義及檢測,像下面一樣
interface Student{
name:string,
age:number
}
interface Teacher{
name:string,
sex:string
}
const sayHello = (user) => {
console.log(user.name)
}
let st: Student ={
name: '張珊',
age:18
}
let te :Teacher = {
name:"歷史",
sex:"男"
}
sayHello(st);
sayHello(te);
但是我們發現,
sayHello
中引數user
的推斷型別是
這個不是我們想要的,所以我們去定義這個user
的型別,用什麼呢?是Student
還是Teacher
,當然是我全都要了
const sayHello = (user: Student | Teacher) => {
console.log(user.name)
}
思考,當我們新建物件的時候,這個引數型別是不是一直在新增呢?
這個時候就需要使用我們的介面繼承(提取出相同的屬性,方法,然後其他子類繼承該介面)
interface Person{
name:string
}
interface Student extends Person{
age:number
}
interface Teacher extends Person{
sex:string
}
const sayHello = (user:Person) => {
console.log(user.name)
}
let st: Student ={
name: '張珊',
age:18
}
let te :Teacher = {
name:"歷史",
sex:"男"
}
sayHello(st);
sayHello(te);