ال

الوراثة في JavaScript

1 تمرين

نبذة عن الوراثة

الوراثة أسلوب لإنشاء علاقات أب-ابن بين الأصناف. الصنف الابن (ويُشار إليه أحيانًا بـ_الصنف الفرعي_) يستطيع الوصول إلى السلوك والبيانات التي يعرّفها الصنف الأب (ويُشار إليه أحيانًا بـ_الصنف الأصل_).

class Pet {
  constructor(name) {
    this.name = name;
  }

  introduce() {
    console.log(`This is my pet, ${this.name}.`);
  }
}

class Dog extends Pet {}

const dog = new Dog('Otis');
dog.introduce();
// => This is my pet, Otis.

كلمة extends المفتاحية في تعريف الصنف الابن تُنشئ علاقة بالصنف الأب عبر سلسلة النموذج الأولي.

الكائنات التي ينشئها منشئ الصنف الابن سيكون النموذج الأولي للصنف الأب ضمن سلسلة النموذج الأولي الخاصة بها، ما يمنحها إمكانية الوصول إلى أي طرق أو بيانات يعرّفها الصنف الأب.

const dog = new Dog('Otis');

Dog.prototype.isPrototypeOf(dog); // => true
Pet.prototype.isPrototypeOf(dog); // => true
Pet.prototype.isPrototypeOf(Dog.prototype); // => true

Pet.prototype.hasOwnProperty('introduce'); // => true
Dog.prototype.hasOwnProperty('introduce'); // => false
dog.hasOwnProperty('introduce'); // => false

المنشئات

إذا لم يعرّف الصنف الابن دالة منشئ، استُخدمت دالة منشئ الصنف الأب. لكن إذا عرّف الصنف الابن دالة منشئ خاصة به، وجب استدعاء منشئ الصنف الأب صراحةً. ولاستدعاء منشئ الصنف الأب من داخل نطاق منشئ الصنف الابن، تُستخدم الكلمة المفتاحية super.

class Pet {
  constructor(name) {
    this.name = name;
  }
}

class Dog extends Pet {
  constructor(name, breed) {
    super(name);
    this.breed = breed;
  }
}

const dog = new Dog('Otis', 'Pug');

ولأن منشئ الصنف الأب هو المسؤول عن تهيئة كائن جديد وإسناده إلى this، وجب استدعاؤه قبل أن يستخدم منشئ الصنف الابن الكلمة this.

class Dog extends Pet {
  constructor(name, breed) {
    // using 'this' before calling the parent constructor with 'super'
    this.breed = breed;
    super(name);
  }
}

const dog = new Dog('Otis', 'Pug');
// => ReferenceError: Must call super constructor in derived class before accessing 'this'...

تعريف طرق على الصنف الابن

يستطيع الصنف الابن تعريف سلوك خاص به إضافةً إلى السلوك الموروث من الصنف الأب.

هذا أحد الأسباب الرئيسية لاستخدام الوراثة: الحصول على أصناف ابنة متخصصة لها بياناتها وطرقها الفريدة، وتربطها ببعضها طرق وبيانات مشتركة يوفرها الصنف الأب.

class Dog extends Pet {
  constructor(name, breed) {
    super(name);
    this.breed = breed;
  }

  describe() {
    console.log(`${this.name} is a ${this.breed}.`);
  }
}

const dog = new Dog('Otis', 'Pug');
dog.introduce();
dog.describe();
// => 'This is my pet, Otis.'
// => 'Otis is a Pug.'

تجاوز الطرق الموروثة من الصنف الأب

يستطيع الصنف الابن أيضًا تجاوز سلوك طريقة يعرّفها الصنف الأب، واستبداله أو توسيعه بسلوك يعرّفه الصنف الابن.

class Cat extends Pet {
  // replacing parent class behavior
  introduce() {
    console.log(`This is my cat, ${this.name}.`);
  }
}

class Dog extends Pet {
  constructor(name, breed) {
    super(name);
    this.breed = breed;
  }

  describe() {
    console.log(`${this.name} is a ${this.breed}.`);
  }

  // extending parent class behavior
  introduce() {
    super.introduce();
    this.describe();
  }
}

const cat = new Cat('Milo');
cat.introduce();
// => 'This is my cat, Milo.'

const dog = new Dog('Otis', 'Pug');
dog.introduce();
// => This is my pet, Otis.
// => Otis is a Pug.

لاستدعاء طريقة معرّفة في الصنف الأب من جسم طريقة تحمل الاسم نفسه في الصنف الابن، يجب استخدام الكلمة المفتاحية super للإشارة إلى الصنف الأب.

تعديل عبر GitHub يفتح الرابط في نافذة أو علامة تبويب جديدة

تعلّم الوراثة