TS(四)類

本文目錄:

  • 1.創(chuàng)建對象實例
  • 2.繼承
  • 3.靜態(tài)方法和屬性
  • 4.訪問修飾符
  • 5.readonly
  • 6.抽象類

1.創(chuàng)建對象實例

在js中峦筒,生成實例對象的傳統(tǒng)方法是通過構造函數(shù)
我們首先通過傳統(tǒng)的構造函數(shù)和原型對象的方法來看一下對象實例的創(chuàng)建

function Greeter(message) {
  this.msg = message;
}
Greeter.prototype.greeter = function() {
  return 'hello: ' + this.msg;
};
let m1 = new Greeter('傳統(tǒng)方式創(chuàng)建對象實例');
console.log(m1.msg);
console.log(m1.greeter());

接下來我們再通過類class的方式 生成一個對象實例
我們在ES6的時候悬嗓,實例屬性都是定義在constructor()方法里面垄潮, 在ES7里 我們可以直接將這個屬性定義在類的最頂層,其它都不變放刨,去掉this每瞒,msg和flag就是我們定義在最頂層的實例屬性
constructor(構造函數(shù))方法是類的默認方法
一個類必須有constructor方法,如果沒有顯示定義届氢,一個空的constructor方法會被默認添加

class Greeter {
  msg: string;
  flag: boolean = false;
  // 關于構造函數(shù):
  constructor(message: string) {
    this.msg = message;
  }
  greeter() {
    console.log('這個是在constructor構造函數(shù)外部定義實例屬性:', this.flag);
    return 'hello: ' + this.msg;
  }
}
let g2 = new Greeter('通過類創(chuàng)建的對象實例');
console.log(g2.msg);
console.log(g2.greeter());

接下來我們來分析一些,ES6新增的class語法糖亥至,和構造函數(shù)的一些關系
類class的類型 本質(zhì)上是一個函數(shù); 類本身就指向自己的構造函數(shù)

console.log(typeof Greeter);
console.log(Greeter === Greeter.prototype.constructor);
console.log(g2.greeter === Greeter.prototype.greeter);

通過上面在這個代碼我們也可以發(fā)現(xiàn)悼沈,new類的時候就相當于new構造函數(shù)
調(diào)用類上面的方法就是調(diào)用原型上的方法
在類的實例上面調(diào)用方法,其實就是調(diào)用原型上的方法

2.繼承

  1. 使用繼承來擴展現(xiàn)有的類姐扮,是面向?qū)ο蟮娜筇匦灾?封裝絮供,繼承,多態(tài))
  2. 基類茶敏,父類壤靶,超類是指被繼承的類,派生類惊搏,子類是指繼承于基類的類
  3. ts中類繼承類似于傳統(tǒng)面向?qū)ο缶幊陶Z言中的繼承體系 贮乳,使用extends關鍵字繼承,類中this表示此當前對象本身恬惯,super表父類對象向拆。子類構造函數(shù)中第一行代碼調(diào)用父類構造函數(shù)完成初始化,然后再進行子類的進一步初始化酪耳。子類中可以訪問父類(public浓恳、protected)的成員屬性、方法
  4. 派生類包含了constructor; ts 規(guī)定只要派生類里面自定義了一個constructor函數(shù)就必須在使用this前碗暗,調(diào)用一下super方法
  • ES5 的繼承颈将,實質(zhì)是先創(chuàng)造子類的實例對象this,然后再將父類的方法添加到this上面(Parent.apply(this));ES6 的繼承機制完全不同言疗,實質(zhì)是先將父類實例對象的屬性和方法晴圾,加到this上面(所以必須先調(diào)用super方法),然后再用子類的構造函數(shù)修改this
  • 因為子類自己的this對象噪奄,必須先通過父類的構造函數(shù)完成塑造死姚,得到與父類同樣的實例屬性和方法,然后再對其進行加工勤篮,加上子類自己的實例屬性和方法知允。如果不調(diào)用super方法,子類就得不到this對象

子類方法名和父類相同表示重寫父類方法
業(yè)務需求:我們現(xiàn)在有兩個類叙谨,一個動物類温鸽,一個狗類, 狗也是動物手负,所以會繼承動物類的一些屬性和方法

class Animal {
  name: string;
  constructor(param: string) {
    this.name = param;
  }
  move(distance: number = 0) {
    console.log(`${this.name} 移動了 ${distance}m.`);
  }
}
class Dog extends Animal {
   bark() {
      console.log('狗叫!');
   }
}  
const dog = new Dog('阿黃');
console.log(dog.name);
dog.bark();
dog.move(10);
dog.bark();

上面這個例子中 動物類是基類涤垫,也可以叫父類; 狗是子類也可以叫派生類竟终, 繼承自動物類蝠猬,可以使用父類的任何方法和屬性
我們將上面的代碼稍微做一下修改

class Dog extends Animal {
  dogName2: string;
  constructor(name: string) {
   // 派生類包含了一個構造函數(shù),就必須首先調(diào)用super()方法统捶,會調(diào)用基類的構造函數(shù)榆芦,然后構造子類自己的this
    super(name);
    this.dogName2 = name;
  }
  // 父類也有一個move方法柄粹,我們在子類例自定義move方法,就會重寫從Animal繼承來的move方法匆绣,從而使move方法根據(jù)不同的類而實現(xiàn)不同的功能
  move(distanceInMeters: number = 5) {
    console.log('重寫了基類的move方法');
    super.move(distanceInMeters);
  }
  bark() {
    console.log('狗叫!');
  }
}
let animal1: Animal = new Animal('赤兔');
let dog1: Dog = new Dog('阿黃');
animal1.move();
dog1.move(10);

這個dog1即使被聲明為 Animal類型驻右,也不會調(diào)用父類的move方法,因為它的值就是Dog實例

3.靜態(tài)方法和屬性

  1. ES6中提供了 靜態(tài)方法崎淳, ES7中提供了靜態(tài)屬性堪夭; TS兩者都有
  2. 我們可以認為類具有 實例部分與 靜態(tài)部分這兩個部分。定義靜態(tài)屬性和方法拣凹,只需要在對應的屬性和方法前面加上static即可
class Animal {
  static PI = 3.14159;
  static isAnimal(param) {
    return param instanceof Animal;
  }
}
let cat = new Animal();
console.log(Animal.PI);
console.log(Animal.isAnimal(cat));
cat.isAnimal(cat);
cat.PI;

通過對象cat上來調(diào)用的屬性和方法 叫做對象實例的屬性和方法
通過類名Animal來調(diào)用的 叫靜態(tài)屬性和方法

4.訪問修飾符

  1. ts類中修飾符分為3種森爽; public : 公有(所有)默認;
    protected:保護 (父類+子類)嚣镜;private: 私有(本類)
class Animal {
  public name: string;
  //修飾符還可以使用在構造函數(shù)參數(shù)中爬迟,等同于類中定義該屬性,使代碼更簡潔
  //下面的age屬性就相當于定義在頂部的 一個實例屬性菊匿,借助修飾符也可以定義
   public constructor(theName: string, public age: number = 24) {
     this.name = theName;
   }
   public move() {
      console.log(123);
   }
}
let a1 = new Animal('Lucy');
console.log(a1.name, a1.age);

上面的例子中雕旨,name 被設置為了 public,所以直接訪問實例的 name 屬性是允許的
在ts中捧请,所有的類型默認都是public

  1. private: 當成員被標記成 private時凡涩,它就不能在聲明它的類的外部訪問
class Animal {
  // 這個name屬性就只能在這個類里面訪問,類外部訪問就會報錯
  private name: string;
  constructor(theName: string) {
    this.name = theName;
  }
}
class Dog extends Animal {
  constructor(name) {
   // 派生類的構造函數(shù)必須包含super函數(shù)的調(diào)用
   // 因為父類的構造函數(shù)需要一個參數(shù)疹蛉,所以這里我們需要將name參數(shù)傳遞進去
    super(name);
    // console.log(this.name); //屬性“name”為私有屬性活箕,只能在類“Animal”中訪問。所以在派生類里面訪問也是不允許的
  }
}
let a1 = new Animal('Lucy');
console.log(a1.name);
  1. protected: 屬性和方法 如果是用 protected 修飾可款,則允許在派生類中訪問育韩, private是不允許的
class Animal {
  // 這個name屬性就只能在這個類里面訪問,類外部訪問就會報錯
  protected name: string;
  constructor(theName: string) {
    this.name = theName;
  }
}
class Dog extends Animal {
  constructor(name) {
    super(name);
    // 這個基類的name屬性是 protected受保護的闺鲸,所以可以在派生類里面訪問
    console.log(this.name);
  }
}
let a1 = new Animal('Lucy');
  1. 構造函數(shù)被private修飾, 該類不允許被繼承或者實例化筋讨;只允許被繼承
class Animal {
  public name;
  private constructor(name) {
    this.name = name;
  }
  // protected constructor(name) {
  //   this.name = name;
  // }
}
class Cat extends Animal {
  constructor(name) {
    super(name);
  }
}
let a = new Animal('Jack');

5.readonly

  • 只讀屬性關鍵字,只允許出現(xiàn)在屬性聲明或索引簽名中
  • 可以使用 readonly關鍵字將屬性設置為只讀的摸恍。 只讀屬性必須在聲明時或構造函數(shù)里被初始化
class Animal {
  readonly name: string;
  // 聲明是初始化
  readonly myName: string = '只讀屬性';
  // 注意如果 readonly 和其他訪問修飾符同時存在的話悉罕,需要寫在其后面
  constructor(name: string, public readonly firstName: string) {
    // 構造函數(shù)里面初始化
    this.name = name;
  }
}
let cat2 = new Animal('阿黃', '小白');
console.log(cat2.name, cat2.myName, cat2.firstName);
cat2.name = '張三'; // 編譯報錯,說不能給一個只讀屬性分配一個新值

6.抽象類

  • 抽象類做為其它派生類的基類使用立镶。 它們一般不會直接被實例化壁袄。 不同于接口,抽象類可以包含成員的實現(xiàn)細節(jié)
  • abstract關鍵字是用于定義抽象類和在抽象類內(nèi)部定義抽象方法抽象成員
abstract class Animal {
  name: string = '基類默認值';
  abstract myName: string;
  // 僅僅定義方法的簽名媚媒,不包含方法體
  abstract makeSound(): void;
  move(): void {
    console.log('動物行走');
  }
}

下面這行代碼就會報錯嗜逻, 無法創(chuàng)建抽象類的實例
抽象類不能被實例化, 只能作為基類使用缭召,也就是只能給其他類繼承

let aa2 = new Animal()

抽象類中的抽象方法不包含具體實現(xiàn)并且必須在派生類中實現(xiàn)栈顷。 抽象方法的語法與接口方法相似逆日。 兩者都是定義方法簽名但不包含方法體。 然而萄凤,抽象方法必須包含 abstract關鍵字并且可以包含訪問修飾符

class Dog extends Animal {
  myName: string = '抽象成員';
  // 編譯報錯:非抽象類“Dog”不會實現(xiàn)繼承自“Animal”類的抽象成員“makeSound”
  // 也就是說我們要將基類的抽象方法在派生類這里再實現(xiàn)一次
  makeSound() {
    console.log(`基類的抽象方法必須在派生類中實現(xiàn)--${this.name}--${this.myName}`);
  }
}
let aa3 = new Dog();
console.log(aa3.makeSound());
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末室抽,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子蛙卤,更是在濱河造成了極大的恐慌狠半,老刑警劉巖噩死,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件颤难,死亡現(xiàn)場離奇詭異,居然都是意外死亡已维,警方通過查閱死者的電腦和手機行嗤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來垛耳,“玉大人栅屏,你說我怎么就攤上這事√孟剩” “怎么了栈雳?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長缔莲。 經(jīng)常有香客問我哥纫,道長,這世上最難降的妖魔是什么痴奏? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任蛀骇,我火速辦了婚禮,結果婚禮上读拆,老公的妹妹穿的比我還像新娘擅憔。我一直安慰自己,他們只是感情好檐晕,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布暑诸。 她就那樣靜靜地躺著,像睡著了一般辟灰。 火紅的嫁衣襯著肌膚如雪屠列。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天伞矩,我揣著相機與錄音笛洛,去河邊找鬼。 笑死乃坤,一個胖子當著我的面吹牛苛让,可吹牛的內(nèi)容都是我干的沟蔑。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼狱杰,長吁一口氣:“原來是場噩夢啊……” “哼瘦材!你這毒婦竟也來了?” 一聲冷哼從身側響起仿畸,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤食棕,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后错沽,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體簿晓,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年千埃,在試婚紗的時候發(fā)現(xiàn)自己被綠了憔儿。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡放可,死狀恐怖谒臼,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情耀里,我是刑警寧澤蜈缤,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站冯挎,受9級特大地震影響底哥,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜织堂,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一叠艳、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧易阳,春花似錦附较、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至事示,卻和暖如春早像,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背肖爵。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工卢鹦, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人劝堪。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓冀自,卻偏偏與公主長得像揉稚,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子熬粗,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353