فصل 15: ارث بری (Inheritance) و تراکم (Aggregation) در جاوا

24 مرداد 1397
java-inheritance

وراثت (Inheritance) در جاوا مکانیسمی است که یک شی تمام ویژگی ها و رفتارهای یک شی والد را می گیرد. وراثت قسمت مهمی از برنامه نویسی شی گرا است.

ایده پشت وراثت این است که کلاس های جدید را بر روی کلاس های که قبلا ساخته شده بسازید و از تمامی متدها و فیلدهای آن استفاده کنید و همینطور می توانید فیلد و متدهای جدید را به آن اضافه کنید.

وراثت بیانگر یک رابطه فرزند و والدی یا IS-A است.

دلایل استفاده از وراثت

  1. اورراید کردن متدها (برای دستیابی به چندریختی)
  2. استفاده چندباره از کد

اصطلاحات مربوط به وراثت

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

سینتکس وراثت در جاوا

class Subclass-name extends Superclass-name  
{  
   //methods and fields  
}

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

استفاده از Extend در کلاس

مثال وراثت:

class Employee{  
 float salary=40000;  
}  
class Programmer extends Employee{  
 int bonus=10000;  
 public static void main(String args[]){  
   Programmer p=new Programmer();  
   System.out.println("Programmer salary is:"+p.salary);  
   System.out.println("Bonus of Programmer is:"+p.bonus);  
}  
}

خروجی:

 Programmer salary is:40000.0
 Bonus of programmer is:10000

انواع وراثت در جاوا

بر مبنای کلاس‌ها، سه نوع وراثت در جاوا وجود دارد: تک، چندسطحی و سلسله‌ مراتبی.

ارث بری در کلاس ها

وراثت هیبرید و چندگانه تنها توسط اینترفیس ها پشتیبانی می شود. در مورد اینترفیس ها در ادامه خواهیم آموخت.

وراثت هیبرید در جاوا

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

مثال وراثت تک:

class Animal{  
void eat(){System.out.println("eating...");}  
}  
class Dog extends Animal{  
void bark(){System.out.println("barking...");}  
}  
class TestInheritance{  
public static void main(String args[]){  
Dog d=new Dog();  
d.bark();  
d.eat();  
}}

خروجی:

barking...
eating...

مثال وراثت چندسطحی:

class Animal{  
void eat(){System.out.println("eating...");}  
}  
class Dog extends Animal{  
void bark(){System.out.println("barking...");}  
}  
class BabyDog extends Dog{  
void weep(){System.out.println("weeping...");}  
}  
class TestInheritance2{  
public static void main(String args[]){  
BabyDog d=new BabyDog();  
d.weep();  
d.bark();  
d.eat();  
}}

خروجی:

weeping...
barking...
eating...

مثال وراثت سلسله‌مراتبی:

class Animal{  
void eat(){System.out.println("eating...");}  
}  
class Dog extends Animal{  
void bark(){System.out.println("barking...");}  
}  
class Cat extends Animal{  
void meow(){System.out.println("meowing...");}  
}  
class TestInheritance3{  
public static void main(String args[]){  
Cat c=new Cat();  
c.meow();  
c.eat();  
//c.bark();//C.T.Error  
}}

خروجی:

meowing...
eating...

سوال: چرا از وراثت چندگانه در جاوا پشتیبانی نمی شود؟

برای کاهش پیچیدگی و ساده سازی زبان، وراثت چندگانه در جاوا پشتیبانی نمی شود.

برای مثال در نظر بگیرید که کلاس A، از دو کلاس B و C ارث بری می کند. حال اگر این دو کلاس دارای متدهای مشابه باشند، آنگاه صدا زدن این متد از کلاس A مشکل ایجاد می کند.

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

مثال:

class A{  
void msg(){System.out.println("Hello");}  
}  
class B{  
void msg(){System.out.println("Welcome");}  
}  
class C extends A,B{//suppose if it were  
   
 Public Static void main(String args[]){  
   C obj=new C();  
   obj.msg();//Now which msg() method would be invoked?  
}  
}

خروجی: 

 Compile Time Error

تراکم در جاوا

اگر یک کلاس، یک entity reference داشته باشد آنگاه تراکم اتفاق افتاده است و یک رابطه HAS-A است.

برای مثال به کد زیر دقت کنید: کلاس Employee دارای فیلدهای متنوعی می باشد، یکی از فیلدهای آن Address می باشد که خود یک کلاس جداگانه است و دارای فیلدهای شهر و استان و غیره می باشد.

class Employee{  
int id;  
String name;  
Address address;//Address is a class  
...  
}

روابط بین کلاس ها در Java

دلیل استفاده از تراکم (Aggregation) استفاده چندباره از کد است.

مثالی از تراکم:

class Operation{  
 int square(int n){  
  return n*n;  
 }  
}  
  
class Circle{  
 Operation op;//aggregation  
 double pi=3.14;  
    
 double area(int radius){  
   op=new Operation();  
   int rsquare=op.square(radius);//code reusability (i.e. delegates the method call).  
   return pi*rsquare;  
 }  
  
     
    
 public static void main(String args[]){  
   Circle c=new Circle();  
   double result=c.area(5);  
   System.out.println(result);  
 }  
}

خروجی:  

Output:78.5

معمولا هنگامی که رابطه پدرفرزندی وجود نداشته باشد، استفاده از تراکم برای صرفه جویی در کد پیشنهاد می شود.

وراثت نیز هنگامی پیشنهاد می شود که وراثت در طول عمر آن شی حفظ شود در غیر این صورت تراکم پیشنهاد می شود.

حال همان مثال کارمند و آدرس را به شکل کاملتر بررسی می کنیم:

Address.java

public class Address {  
String city,state,country;  
  
public Address(String city, String state, String country) {  
    this.city = city;  
    this.state = state;  
    this.country = country;  
}  
  
}

Emp.java

public class Emp {  
int id;  
String name;  
Address address;  
  
public Emp(int id, String name,Address address) {  
    this.id = id;  
    this.name = name;  
    this.address=address;  
}  
  
void display(){  
System.out.println(id+" "+name);  
System.out.println(address.city+" "+address.state+" "+address.country);  
}  
  
public static void main(String[] args) {  
Address address1=new Address("gzb","UP","india");  
Address address2=new Address("gno","UP","india");  
  
Emp e=new Emp(111,"varun",address1);  
Emp e2=new Emp(112,"arun",address2);  
      
e.display();  
e2.display();  
      
}  
}

خروجی:

Output:111 varun
       gzb UP india
       112 arun
       gno UP india
نویسنده شوید
دیدگاه‌های شما (1 دیدگاه)

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

علی زمانی
20 مرداد 1398
عالی بود ممنون

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.