وراثت(Inheritance) در جاوا اسکریپت


در این نوشته نحوه پیاده سازی وراثت(inheritance ) در جاوا اسکریپت با استفاده از extends
و super
در ES6 را یاد می گیریم.
پیاده سازی inheritance در جاوا اسکریپت با استفاده از extends و super
قبل از ES6 ، پیاده سازی inheritance نیاز به چندین مرحله داشت. یکی از رایج ترین استراتژی ها ، prototypal inheritanc است.
مثال زیر نشان می دهد که Bird
چطور properties ها را Animal
با استفاده از تکنیک prototypal inheritance به ارث می برد.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
function Animal(legs) { this.legs = legs; } Animal.prototype.walk = function() { console.log('walking on ' + this.legs + ' legs'); } function Bird(legs) { Animal.call(this, legs); } Bird.prototype = Object.create(Animal.prototype); Bird.prototype.constructor = Animal; Bird.prototype.fly = function() { console.log('flying'); } var pigeon = new Bird(2); pigeon.walk(); // walking on 2 legs pigeon.fly(); // flying |
ES6 این مراحل را با استفاده از کلمه های کلیدی extends
و super
بسیار آسان کرده است.
مثال زیر کلاس Animal و Bird را تعریف کرده و وراثت را از طریق کلمه های کلیدی extends
و super
ایجاد می کند.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
class Animal { constructor(legs) { this.legs = legs; } walk() { console.log('walking on ' + this.legs + ' legs'); } } class Bird extends Animal { constructor(legs) { super(legs); } fly() { console.log('flying'); } } let bird = new Bird(2); bird.walk(); bird.fly(); |
در ابتدا،کلمه کلیدی extends
باعث می شود که کلاس Bird
از کلاس Animal
ارث بری کند:
1 2 3 |
class Bird extends Animal { // ... } |
کلاس Animal
با نام base class یا parent class شناخته می شود در حالی که کلاس Bird
با derived class یا child class شناخته می شود.با این کار ، کلاس Bird تمام method ها وproperties های کلاس Animal را به ارث می برد.
سپس در سازنده کلاس Bird
‘s ، فراخوانی ()super برای invoke سازنده کلاس Animal
‘s با legs
argument انجام می شود.
جاوا اسکریپت در صورت داشتن constructor در child class نیاز دارد تا ()super را فراخوانی کند.همانطور که در کلاس Bird مشاهده می کنید ، super(legs) معادل عبارت زیر در ES5 است:
1 |
Animal.call(this, legs); |
اگر کلاس Bird
دارای constructor(سازنده) نباشد، شما نیاز نیست هیچ کار دیگری انجام دهید:
1 2 3 4 5 |
class Bird extends Animal { fly() { console.log('flying'); } } |
این قطعه کد معادل کلاس زیر است:
1 2 3 4 5 6 7 8 |
class Bird extends Animal { constructor(...args) { super(...args); } fly() { console.log('flying'); } } |
با این وجود اگر child class دارای constructor است، نیاز است که ()super فراخوانی شود.برای مثال، کد زیر error بر می گرداند.
1 2 3 4 5 6 7 |
class Bird extends Animal { constructor(legs) { } fly() { console.log('flying'); } } |
Error :
1 |
ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor |
برای مثال، اگر شما قصد داشته باشید color
property را در کلاس Bird
مقداردهی کنید، باید مشابه زیر عمل کنید:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
class Bird extends Animal { constructor(legs, color) { super(legs); this.color = color; } fly() { console.log("flying"); } getColor() { return this.color; } } let pegion = new Bird(2, "white"); console.log(pegion.getColor()); |
Shadowing methods
ES6 اجازه می دهد تا child class و parent class متدهایی با نام یکسان داشته باشند.در این حالت ، هنگامی که method یک object از کلاس فرزند(child class) را فراخوانی می کنید ، method در کلاس رزند روی method در کلاس والد shadow می اندازد.
در مثال زیر کلاس Dog از کلاس Animal در واقغ extends شده و متد () walk را مجدد تعریف کرده است:
1 2 3 4 5 6 7 8 9 10 11 |
class Dog extends Animal { constructor() { super(4); } walk() { console.log(`go walking`); } } let bingo = new Dog(); bingo.walk(); // go walking |
برای فراخوانی method از کلاس والد در کلاس فرزند، باید از super.method(arguments) مشابه زیر استفاده کرد:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
class Dog extends Animal { constructor() { super(4); } walk() { super.walk(); console.log(`go walking`); } } let bingo = new Dog(); bingo.walk(); // walking on 4 legs // go walking |
Inheriting static members
علاوه بر properties ها و methods ها ، کلاس فرزند نیز تمام properties ها و methods های static کلاس والد را به ارث می برد. مثلا:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
class Animal { constructor(legs) { this.legs = legs; } walk() { console.log('walking on ' + this.legs + ' legs'); } static helloWorld() { console.log('Hello World'); } } class Bird extends Animal { fly() { console.log('flying'); } } |
در این مثال کلاس Animal
یک static method به نام ()helloWorld دارد که این method با ()Bird.helloWorld در دسترس است و دقیقا رفتاری مشابه با ()Animal.helloWorld دارد:
1 |
Bird.helloWorld(); // Hello World |
خلاصه
- برای پیاده سازی وراثت(inheritance ) در ES6 از کلمه کلیدی extends استفاده می شود.
- فراخونی super(arguments) در سازنده کلاس فرزند(child class’s constructo) باعث فراخوانی کلاس والد(parent class’s constructor) می شود.
- با استفاده از کلمه کلیدی
super
می توانید method های کلاس والد را در method های کلاس فرزند فراخوانی کنید
دیدگاهتان را بنویسید