تا %60 تخفیف خرید برای 8 نفر با صدور مدرک فقط تا
00 00 00
در توسینسو تدریس کنید

آموزش جاوا (Java) قسمت 33 : وراثت کلاس ها و انواع آن

با سلام به همه دوستان و همراهان Itpro. آموزش هایی که تا به حال در مورد زبان جاوا گفتیم بیشتر مطالب مقدماتی یادگرفتن زبان برنامه نویسی جاوا بود و به گونه ای مطالب گفته شده پایه برنامه نویسی زبان جاوا محسوب می شوند. ولی در مطالب گفته شده آنچنان به مفاهیم شئ گرایی و خواص شئ گرایی جاوا پرداخته نشد. حال از این آموزش به بعد قصد داریم که مطالب شئ گرایی را در جاوا بیان کنیم و هرکدام را به صورت مفصل توضیح دهیم. امیدوارم که بتوانم این زبان قدرتمند و پراستفاده را به صورت درست شرح دهم. یکی از خواص شئ گرایی که قبلا هم کم و بیش در مورد آن گفتیم ارث بری یا inheritance است. ارث بری را می توان این گونه تعریف کرد که یک کلاس خصوصیاتی را از یک کلاس دیگر به ارث می برد. با استفاده از ارث بری اطلاعات به ارث برده شده طبق ارث بری آنها قابل مدیریت است. کلاسی که خصوصیات را به ارث می برد زیرکلاس یا کلاس مشتق شده یا کلاس فرزند نام دارد و کلاسی که خصوصیاتی را ارث می دهد به عنوان کلاس پایه و یا کلاس والد شناخته می شود.

کلمه کلیدی extends

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

class Super{
   .....
   .....
}

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

}

برای این که وراثت در کلاس ها در زبان جاوا را بهتر بیان کنیم مثالی در ادامه آورده ایم.در این مثال دو کلاس آورده ایم که یکی Calculation و دیگری MyCalculation نام دارد. با استفاده از کلمه extends کلاس MyCalcuation متدهای addition و subtraction را از کلاس Calculation به ارث می برد.

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 Substraction(int x,int y){
      z = x-y;
      System.out.println("The difference between the given numbers:"+z);
   }
   
}

public class MyCalculation 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;
      MyCalculation demo = new My_Calculation();
      demo.addition(a, b);
      demo.Substraction(a, b);
      demo.multiplication(a, b);      
   }

}

حال اگر برنامه بالا را کامپایل و اجرا کنید نتیجه اجرای برنامه به شکل زیر خواهد بود:

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

در برنامه بالا شیئی که از کلاس MyCalculation ساخته می شود همه ی متدهای کلاس والد را نیز به همراه خود دارد. به این معنی که با استفاده از شئ فرزند می توان به متدها و فیلدهای public کلاس والد هم دسترسی داشت. اگر شما شیئی داشته باشید که از کلاس والد ساخته شده باشد این شئ فقط می تواند به اعضای کلاس والد دسترسی داشته باشد در حالی که کلاس از کلاس فرزند هم به اعضای کلاس فرزند و هم به اعضای کلاس پدر دسترسی دارد. برای مثال در برنامه بالا اگر شیئی از کلاس Calculation ساخته شده باشد. این شئ نمی تواند به متد multiplication دسترسی داشته باشد. زیرا که این متد مربوط به کلاس فرزند یعنی MyCalculation می باشد. دقت داشته باشید که یک کلاس فرزند همه ی اعضا(فیلدها و متدها و کلاس های داخلی) را از کلاس والد به ارث می برد. Constructor ها جزء این اعضا محسوب نمی شوند و به ارث برده نمی شوند اما سازنده کلاس والد می تواند از داخل کلاس فرزند فراخوانی شود.

کلمه کلیدی super

این کلمه کلیدی شبیه به کلمه this می باشد ولی این کلمه کلیدی برای ارجاع به کلاس والد استفاده می شود. یکی از کاربرد های آن تفاوت قایل شدن بین اعضای خود کلاس و اعضای کلاس والد است. این کار در صورتی که نام یکی از اعضا هم در کلاس والد تعریف شده باشد و هم در کلاس فرزند. کاربرد دیگر این کلمه کلیدی فراخوانی constructor کلاس والد است.

تفاوت قایل شدن بین اعضا

اگر یک کلاس مشخصات خود را از کلاس دیگری ارث برده باشد و اگر اعضای کلاس پدر نام هایی داشته باشند که آن نام در بین اعضای کلاس فرزند نیز موجود باشد اگر در داخل کلاس فرزند نام آن عضو را قرار بدهیم، کامپایلر عضو مربوط به کلاس فرزند را در نظر می گیرد و اگر بخواهیم به کلاس پدر دسترسی داشته باشیم از کلمه کلیدی super استفاده خواهیم کرد. برای درک بهتر این کلمه کلیدی و استفاده از آن برای تفاوت قایل شدن بین اعضای کلاس والد و فرزند مثالی آورده ایم که در کد زیر مشاهده می کنید. در این برنامه یک کلاس به نام SubClass و یک کلاس دیگر به نام SuperClass داریم که هر دوی آن ها بک متد به نام display دارد. هر کدام از این متدها دارای پیاده سازی جداگانه ای هستند. در برنامه زیر می بینید که هرکدام از این متد ها را چگونه فراخوانی می کنیم و چگونه بین آنها تفاوت می گذاریم.

class SuperClass{

   int num = 20;
   
   //display method of superclass
   public void display(){   
      System.out.println("This is the display method of superclass");
   }	

}

public class SubClass 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 myMethod(){
	  
      //Instantiating subclass
      SubClass sub = new SubClass();
	  
      //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[]){
      SubClass obj = new SubClass();
      obj.myMethod();
      
   }
}

اگر برنامه بالا را کامپایل و اجرا کنید نتیجه اجرای برنامه به شکل زیر خواهد بود:

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 پیشفرض که بدون پارامتر ورودی است به ارث می برد. اما اگر بخواهید یکی از constructor های کلاس والد که دارای پارامتر ورودی است را فراخوانی کنید باید از کلمه کلیدی super استفاده کنید. برای مثال و درک بهتر این کاربرد super به برنامه زیر دقت کنید. در این برنامه نشان می دهیم که چگونه با استفاده از کلمه کلیدی super می توان constructor مربوط به کلاس والد را فراخوانی کنیم. این برنامه یک کلاس والد و یک کلاس فرزند دارد که کلاس والد یک رشته را به عنوان پارامتر ورودی constructor می گیرد. و در کلاس فرزند با استفاده از کلمه کلیدی super آن 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 می توان ساخت. برای مثال به تعریف کلاس های زیر که تعریف حیوانات است توجه کنید:

public class Animal{
}

public class Mammal extends Animal{
}

public class Reptile extends Animal{
}

public class Dog extends Mammal{
}

با توجه به تعاریف بالا و طبق قوانین شئ گرایی جمله های زیر صادق است:

  • Mammal یک Animal است زیرا از آن ارث برده است.
  • Reptile یک Animal است زیرا از آن ارث برده است.

* Dog یک Mammal است.

  • Dog یک Animal است.

با استفاده از کلمه کلیدی extends کلاس های فرزند همه ی خصوصیات کلاس های والد را به ارث می برند. به طور مثال در کد بالا کلاس Dog از کلاس Mammal ارث برده است ولی از آنجا که کلاس Mammal خود از کلاس Animal به ارث برده است پس کلاس Dog خصوصیات کلاس Animal را نیز به ارث خواهد برد. دقت داشته باشید که کلاس فرزند نمی تواند اعضای private کلاس والد را به ارث ببرد. برای مثال به کد زیر دقت کنید.

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 می پردازیم. این کلمه کلید زمانی به کار برده می شود که بخواهیم خصوصیات موجود در یک اینترفیس را به ارث ببریم. برای اینترفیس ها نمی توان از کلمه کلیدی extends استفاده کرد. خود اینترفیس نیز نمی تواند از کلاسی ارث ببرد. برای مثال به کد زیر دقت کنید:

public interface Animal {
}

public class Mammal implements Animal{
}

public class Dog extends Mammal{
}

دقت داشته باشید که برای این که مشخص کنیم که یک کلاس از کلاس دیگر به ارث برده است یا خیر از کلمه کلیدی instaceof استفاده می کنیم.

رابطه Has-A

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

public class Vehicle{}
public class Speed{}

public class Van extends Vehicle{
	private Speed sp;
} 

کد بالا نشان می دهد که کلاس Van خصوصیت Speed را دارد. با استفاده از کلاس جداگانه برای Speed دیگر نیازی نداریم که کل کدهای کلاس Speed را برای Van نیز بیاوریم و فقط از آن استفاده می کنیم. با استفاده از خواص شئ گرایی نیازی نیست که کاربران بدانند که کار واقعی را کدام کلاس انجام می دهد و بهتر است این مسئله از دید کاربر مخفی باشد. در مثال بالا هم کلاس Van پیاده سازی Speed را از دید کاربر مخفی کرده است. تنها کاری که کلاس Van از Speed انتظار دارد این است که کارهای خاصی را انجام دهد.

انواع ارث بری

ارث بری انواع مختلفی دارد که در تصویر زیر مشاهده می کنید

آموزش جاوا (Java) قسمت 33 : وراثت کلاس ها و انواع آن

دقت داشته باشید که زبان جاوا از ارث بری چندگانه پشتیبانی نمی کند. این به این معنی است که جلوی کلمه extends فقط یک کلاس می توان قرار داد. ولی می توان با استفاده از اینترفیس ها و سلسله مراتب ارث بری، ارث بری چندگانه را شبیه سازی کرد.Itpro باشید

نویسنده: مهدی عادلی فر

منبع: جزیره برنامه نویسی و توسعه نرم افزار وب سایت توسینسو

هرگونه نشر و کپی برداری بدون ذکر منبع و نام نویسنده دارای اشکال اخلاقی می باشد.

نظر شما
برای ارسال نظر باید وارد شوید.
1 نظر
افرادی که این مطلب را خواندند مطالب زیر را هم خوانده اند