Oruji.org
Oruji.orgPersian Tutorials
ورود
ویرایش: 1396/11/23 22:58

آموزش ارث بری یا وراثت (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 در وراثت آورده شده است، برنامه زیر دارای دو کلاس به نام های Sub_class و Super_class می باشد، هر دو دارای متدی با نام display() ولی با پیاده سازی متفاوت هستند، و همچنین دارای متغیری به نام num با مقادیر متفاوت. ما متد display() هر دو کلاس را فراخوانی می کنیم و همچنین مقدار متغیر num هر دو کلاس را چاپ می کنیم. در اینجا شما استفاده از کلمه کلیدی super و متمایز کردن اعضای هر دو کلاس را مشاهده می کنید.

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

خروجی

This is the display method of subclass This is the display method of superclass value of the variable named num in sub class:10 value of the variable named num in super class:20

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

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

super(values);

نمونه کد

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

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

خروجی

The value of the variable named age in super class 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) چندگانه رهایی می دهد.