JavaScript面向對象輕鬆入門之繼承(demo by ES五、ES6)

  繼承是面向對象很重要的一個概念,分爲接口繼承和實現繼承,接口繼承即爲繼承某個對象的方法,實現繼承即爲繼承某個對象的屬性。JavvaScript經過原型鏈來實現接口繼承、call()apply()來實現實現繼承。瀏覽器

  接口繼承的實如今ES5中是比較麻煩,在其它OOP語言中一個extends關鍵字就能夠實現,但在ES5中要經過原型鏈去模擬,很是難理解,對初學者很不友好,而且有好幾種接口繼承的方式。本文爲了對初學者更友好,並不打算讓讀者瞭解接口繼承的原理,而是直接把接口繼承實現方法封裝成一個函數,你們只要把這個函數拿過去用就能夠了。app

  相關概念:父類(超類)即爲被繼承者,子類(派生類)即繼承者函數

接口繼承函數extend():

 1 function extend(subClass, superClass) {
 2     function o() {
 3         this.constructor = subClass;
 4     }
 5     o.prototype = superClass.prototype;
 6     subClass.prototype = new o();
 7     return subClass.prototype;
 8 }
 9 /*
10 subClass是子類,superClass是父類,extend函數讓subClass繼承superClass的原型方法,並返回subClass的原型;
11 這種繼承方式也是用的最多的,而且ES6的extends也是經過這種方式實現的,能夠說是比較權威的用法;
12 */

ES5繼承DEMO:

 1 function Animal(shoutVoice,speed){
 2     this._shoutVoice = shoutVoice;//string
 3     this._speed = speed;//string
 4 }
 5 Animal.prototype.getSpeed = function(){
 6     return this._speed;
 7 };
 8 Animal.prototype.shout = function(){
 9     console.log(this._shoutVoice);
10 };
11 Animal.prototype.run = function(){
12     console.log('嘿嘿,吃我灰吧!個人速度但是有'+this._speed);
13 };
14 
15 function Dog(){
16     Animal.call(this,'汪汪汪!','10m/s');
17     //實現繼承:調用Animal的構造函數,繼承Animal類的屬性,第一個參數必須是this;
18 }
19 //接口繼承:extends函數讓Dog類繼承Animal類的的原型方法並返回Dog的新的原型prototype;
20 var DogP = extend(Dog,Animal);
21 /*能夠繼續給的Dog類的prototype添加方法*/
22 DogP.gnawBone = function() {
23     console.log('這是本狗最幸福的時候');
24 }
25 /*也能夠把父類的方法覆蓋掉*/
26 DogP.run = function(){
27     console.log('這是Dog類上的run方法,不是Animal類的');
28     /*雖然覆蓋掉了,但實際上Animal類的run方法還在,也能夠經過這種方式訪問父類的方法,
29     對原理有興趣的同窗能夠了解一下原型鏈*/
30     Animal.prototype.run.call(this);
31 }
32 var dog = new Dog();
33 console.log(dog.getSpeed());//log: '10m/s'
34 dog.shout();//log: '汪汪汪!'
35 dog.run();
36 /*log:
37 '這是Dog類上的run方法,不是Animal類的'
38 '嘿嘿,吃我灰吧!個人速度但是有10m/s'
39 */
40 dog.gnawBone();//log: '這是本狗最幸福的時候'42 /*其它類繼承Animal類*/
43 function Snake(){
44     Animal.call(this,'嘶!嘶!嘶!','5m/s');
45 }
46 var SnakeP = extend(Snake,Animal);
47 /*Dog類也能夠繼續被繼承*/
48 function PoodleDog(){
49     Dog.call(this);
50     this._breed = 'poodle';
51 }
52 var PoodleDogP = extend(PoodleDog,Dog);
53 /*理論上講能夠無限繼承下去,如瀏覽器DOM對象就繼承了不少個對象,組成了一個長長的原型鏈
54 如一個div標籤對象的類繼承順序:
55 HTMLDivElement<HTMLElement<Element<Node<EventTarget<Object
56 但咱們的項目中最好別超過3次,不然就不太好控制了;*/

注意事項:

  *繼承的次數不該過多,不然子類一不當心就把父類的屬性方法給覆蓋了;
  *咱們能夠把繼承的對象做爲成員屬性,即組合,儘可能少用繼承,多用組合;
  *父類的屬性和方法最好別太多,過多也容易被子類覆蓋,能夠抽象成一個對象來管理過多的屬性和方法。
  *繼承增長了耦合,因此父類封裝性必定要好,儘可能下降與子類的耦合,
  *父類的設計要有前瞻性,具有必定的擴展能力,你也不但願從此修改父類的時候,再去修改全部的子類吧?this

  *父類儘可能只定義方法,不定義屬性,即構造函數最好是空函數;spa

ES6繼承DEMO:

  ES6實現繼承就方便不少了,因爲TypeScript實現繼承和ES6差很少,因此這章就不貼出TypeScript的Demo了prototype

 1 class Animal{
 2     constructor(shoutVoice,speed){
 3         this._shoutVoice = shoutVoice;//string
 4         this._speed = speed;//string
 5     }
 6     get speed(){
 7         return this._speed;
 8     }
 9     shout(){
10         console.log(this._shoutVoice);
11     }
12     run(){
13         console.log('嘿嘿,吃我灰吧!個人速度但是有'+this._speed);
14     }
15 }
16 class Dog extends Animal{
17     constructor(){
18         super('汪汪汪!','10m/s');//至關於Animal.call(this,'汪汪汪!','10m/s');
19     }
20     gnawBone() {
21         console.log('這是本狗最幸福的時候');
22     }
23     run(){
24         console.log('這是Dog類上的run方法,不是Animal類的');
25         super.run();//至關於Animal.prototype.run.call(this);
26     }
27 }
28 class PoodleDog extends Dog{
29     constructor(){
30         super();
31         this._breed = 'poodle';
32     }
33     get breed(){
34         return this._breed;
35     }
36 }
37 let poodleDog = new PoodleDog();
38 console.log(poodleDog.breed);//log: 'poodle'
39 console.log(poodleDog.speed);//log: '10m/s'
40 poodleDog.shout();//log: '汪汪汪!'
41 poodleDog.run();
42 /*log:
43 '這是Dog類上的run方法,不是Animal類的'
44 '嘿嘿,吃我灰吧!個人速度但是有10m/s'
45 */
46 poodleDog.gnawBone();//log: '這是本狗最幸福的時候'

後話

  js的繼承與其它OOP語言有一些不一樣的地方,因此最終仍是要深入的理解原型、原型鏈才能靈活運用,但願你們有時間必定要把這部分知識補上;設計

  若是你喜歡做者的文章,記得收藏,你的點贊是對做者最大的鼓勵;code

  做者會盡可能每週更新一章,下一章是講多態;對象

  你們有什麼疑問能夠留言或私信做者,做者儘可能第一時間回覆你們;blog

  若是老司機們以爲那裏能夠有不恰當的,或能夠表達的更好的,歡迎指出來,我會盡快修正、完善。

相關文章
相關標籤/搜索