amoozesh.org
amoozesh.orgPersian Tutorials
ورود
ویرایش: 1398/2/16 22:50

آموزش ارث بری یا وراثت (Inheritance) در جاوا

در این آموزش از کتاب برخط جاوا، ارث بری یا وراثت (Inheritance) را می توان پردازشی تعریف کرد، که در آن یک کلاس خصوصیات (متدها و فیلدها) کلاسی دیگر را بدست می آورد. با استفاده از ارث بری، اطلاعات قابلیت مدیریت به صورت سلسه مراتبی را خواهند داشت.

کلاسی که خصوصیات کلاس دیگری را ارث بری می نماید کلاس فرزند، و کلاسی که خصوصیات آن به ارث برده شده است را کلاس پدر می نامیم.

کلمه کلیدی extends در وراثت

extends کلمه کلیدی ای است که برای ارث بری خصوصیات یک کلاس استفاده می شود. مثال زیر نحوه استفاده از extends را نشان می دهد:

class Super { ..... ..... } class Sub extends Super { ..... ..... }

نمونه کد

مثال زیر وراثت در جاوا را شرح می دهد. در این مثال، دو کلاس با نام های Calculation و My_Calculation را مشاهده می کنید. با استفاده از کلمه کلیدی extends، کلاس My_Calculation متد های addition() و substraction() موجود در کلاس Calculation را ارث بری می نماید. برنامه زیر را در فایلی با نام My_Calculation.java کپی کنید.

class Calculation { int z; public void addition(int x, int y) { z = x y; System.out.println("The sum of the given numbers:" z); } public void subtraction(int x, int y) { z = x - y; System.out.println("The difference between the given numbers:" z); } } public class My_Calculation extends Calculation { public void multiplication(int x, int y) { z = x * y; System.out.println("The product of the given numbers:" z); } public static void main(String args[]) { int a = 20, b = 10; My_Calculation demo = new My_Calculation(); demo.addition(a, b); demo.Subtraction(a, b); demo.multiplication(a, b); } }

کامپایل و اجرای کد بالا در زیر نشان داده شده است.

javac My_Calculation.java java My_Calculation

خروجی برنامه:

The sum of the given numbers:30 The difference between the given numbers:10 The product of the given numbers:200

در برنامه داده شده، زمانی که یک شیء از My_Calculation ایجاد می شود، یک کپی از محتویات پدر درون آن قرار می گیرد. به همین خاطر است که با استفاده از کلاس فرزند یا subclass شما می توانید به خصوصیات پدر یا superclass دسترسی پیدا کنید.

متغیر reference کلاس پدر می تواند شیء کلاس فرزند را قبول کند، ولی با استفاده از این متغیر شما تنها می توانید به خصوصیات پدر دسترسی پیدا کنید، بنابراین توجه داشته باشید که برای دسترسی به خصویات هر دو، توصیه می شود که متغیر reference را با کلاس فرزند ایجاد کنید.

همانطور که برنامه بالا را ملاحظه می کنید، شما می توانید کلاس را همانند زیر مقدار دهی کنید. ولی با استفاده از متغیر reference کلاس پدر (که در مثال زیر cal نام دارد) شما نمی توانید متد multiplication() را که متعلق به فرزند یعنی My_Calculation است را فراخوانی کنید.

توجه : کلاس فرزند تمامی اعضای (متدها، فیلدها، کلاس های nested) پدر را به ارث می برد. Cunstructor ها جزء اعضاء نیستند، بنابراین آن ها توسط فرزند به ارث برده نمی شوند، ولی constructor یا سازنده ی پدر می تواند در فرزند فراخوانی شود.

کلمه کلیدی super

کلمه کلیدی super همانند کلمه کلیدی this می باشد. در زیر مواردی را که در آن از super استفاده می شود آمده است.

متمایز کردن اعضاء

اگر کلاسی خصوصیات کلاس دیگر را ارث بری کند. و اگر اعضای (متدها، فیلدها ...) کلاس پدر اسامی همسان با اسامی اعضای کلاس فروند داشته باشند، برای متمایز کردن این متغیر ها ما همانند زیر از کلمه کلیدی super استفاده می کنیم.

super.variable super.method();

نمونه کد

در زیر مثالی برای شرح استفاده از کلمه کلیدی super در وراثت آورده شده است، برنامه زیر دارای دو کلاس به نام های Child و Parent می باشد، هر دو دارای متدی با نام display() ولی با پیاده سازی متفاوت هستند، و همچنین دارای متغیری به نام num با مقادیر متفاوت. ما متد display() هر دو را فراخوانی می کنیم و همچنین مقدار متغیر num هر دو را چاپ می کنیم. در اینجا شما استفاده از کلمه کلیدی super و متمایز کردن اعضای هر دو کلاس را مشاهده می کنید.

class Parent { int num = 20; // display method of Parent public void display() { System.out.println("This is the display method of Parent"); } } public class Child extends Parent { int num = 10; // display method of Child public void display() { System.out.println("This is the display method of Child"); } public void my_method() { // Instantiating Child Child sub = new Child(); // Invoking the display() method of Child sub.display(); // Invoking the display() method of Parent super.display(); // printing the value of variable num of Child System.out.println("value of the variable named num in Child:" sub.num); // printing the value of variable num of Parent System.out.println("value of the variable named num in Parent:" super.num); } public static void main(String args[]) { Child obj = new Child(); obj.my_method(); } }

خروجی

This is the display method of Child This is the display method of Parent value of the variable named num in Child:10 value of the variable named num in Parent:20

فراخوانی Constructor کلاس پدر

در صورتی که کلاسی خصوصیات کلاسی دیگر را ارث بری کند، کلاس فرزند به طور خودکار constructor پیشفرض پدر را بدست می آورد. ولی اگر بخواهید contructor دارای پارامتر کلاس پدر را فراخوانی کنید، نیاز خواهید داشت مانند زیر از کلمه کلید super استفاده کنید.

super(values);

نمونه کد

برنامه زیر شرح استفاده از کلمه کلیدی super برای فراخوانی constructor دارای پارامتر کلاس نشان داده شده است. این برنامه حاوی یک کلاس پدر و کلاس فرزند می باشد، که کلاس پدر یک constructor دارای پارامتر دارد که یک مقدار رشته را قبول می کند.

class Parent { int age; Parent(int age) { this.age = age; } public void getAge() { System.out.println("The value of the variable named age in Parent is: " age); } } public class Child extends Parent{ Parent(int age) { super(age); } public static void main(String argd[]) { Child s = new Child(24); s.getAge(); } }

خروجی

The value of the variable named age in Parent is: 24

رابطه IS-A

در مفاهیم شیءگرایی رابطه IS-A را می توان این چنین بیان کرد که: یک شیء نوعی از یک شیء دیگر است. اجازه دهید ببینیم که کلمه کلیدی extends چگونه برای وراثت یا ارث بری (Inheritance) در زبان جاوا استفاده می شود.

public class Animal { } public class Mammal extends Animal { } public class Reptile extends Animal { } public class Dog extends Mammal { }

بر اساس مثال بالا، در مفاهیم شیءگرا و وراثت موارد زیر درست می باشند:

با توجه به رابطه IS-A، می توان عبارات زیر را بیان کرد:

با استفاده از کلمه کلیدی extends در جاوا (Java)، کلاس های فرزند قادر خواهند بود تمامی خصوصیات کلاس پدر را ارث بری کنند، البته به جز خصوصیاتی که در کلاس پدر به طور private تعریف شده اند.

با استفاده از عملگر instanceof می تواند اطمینان حاصل کرد که، Mammal در واقع یک Animal است.

مثال:

class Animal { } class Mammal extends Animal { } class Reptile extends Animal { } public class Dog extends Mammal { public static void main(String args[]) { Animal a = new Animal(); Mammal m = new Mammal(); Dog d = new Dog(); System.out.println(m instanceof Animal); System.out.println(d instanceof Mammal); System.out.println(d instanceof Animal); } }

خروجی برنامه:

true true true

پس از درک کلمه کلیدی extends در وراثت، اجازه دهید نگاهی به کلمه کلیدی implements، جهت استفاده در رابطه IS-A بیاندازیم.

کلمه کلیدی implements جهت استفاده کلاس ها برای ارث بری از interface ها بکار می رود. interface ها هرگز نمی توانند توسط کلاس ها extends شوند.

مثال:‌

public interface Animal {} public class Mammal implements Animal { } public class Dog extends Mammal { }

کلمه کلیدی instanceof

اجازه دهید جهت بررسی اینکه Mammal در واقع یک Animal و Dog در واقع یک Animal می باشد را با استفاده از کلمه کلیدی instanceof انجام دهیم.

interface Animal{} class Mammal implements Animal{} public class Dog extends Mammal{ public static void main(String args[]){ Mammal m = new Mammal(); Dog d = new Dog(); System.out.println(m instanceof Animal); System.out.println(d instanceof Mammal); System.out.println(d instanceof Animal); } }

خروجی برنامه:

true true true

رابطه HAS-A

این نوع رابطه اساسا مبنی بر استفاده می باشد. این رابطه تعیین می کند که آیا یک کلاس دارای خصوصیتی از نوع یک کلاس دیگر می باشد یا خیر. این نوع رابطه باعث کاهش کدهای تکراری و همچنین باگ ها در برنامه می شود.

اجازه دهید مثالی بیاوریم:

public class Vehicle {} public class Speed {} public class Van extends Vehicle { private Speed sp; }

این نشان می دهد که Van دارای Speed می باشد. با داشتن یک کلاس جدای Speed، دیگر نیازی به قرار دادن تمامی کدهای مربوط به سرعت (Speed) درون Van نیست. که این باعث می باشد که از Speed بتوان در برنامه های دیگر دوباره استفاده کرد.

نکته بسیار مهم در جاوا این است که، یک کلاس می تواند تنها از یک کلاس دیگر ارث بری کند. بدین معنی که یک کلاس نمی تواند از بیشتر از یک کلاس ارث بری کند. بنابراین کد زیر اشتباه است:

public class extends Animal, Mammal {}

با این وجود، یک کلاس می تواند از یک یا بیشتر از interface ها ارث بری کند. این جاوا را از غیر ممکن بودن وراثت (Inheritance) چندگانه رهایی می دهد.