شنبه ۲۹ دي ۱۴۰۳
Tut24 آموزش برنامه نویسی و مجله تخصصی فناوری ورود/عضویت

آموزش جاوا - ارث بری

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

کلاسی که ویژگی‌های کلاس دیگر را به دست می‌آورد، زیرکلاس (کلاس مشتق شده، کلاس فرزند) و کلاسی که ویژگی‌هایش به ارث داده می‌شوند، بالاکلاس (کلاس پایه، کلاس والد) نامیده می‌شود.

کلیدواژه extends

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

دستورالعمل


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

کد نمونه

در ادامه، یک نمونه از ارث‌بری در جاوا آورده شده است. در این نمونه، دو کلاس به نام Calculation و My_Calculation وجود دارد.

با استفاده از کلیدواژه extends، کلاس My_Calculation از متدهای addition() و Subtraction() کلاس 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 ایجاد می‌شود، یک کپی از محتویات کلاس پایه درون آن ایجاد می‌شود. به همین دلیل، با استفاده از شیء زیرکلاس، می‌توانید به اعضای یک کلاس پایه دسترسی پیدا کنید.

ارث‌بری

متغیر مرجع Superclass می‌تواند شیء زیرکلاس را نگه دارد، اما با استفاده از آن می‌توانید فقط به اعضای کلاس پایه دسترسی پیدا کنید، بنابراین برای دسترسی به اعضای هر دو کلاس، توصیه می‌شود همیشه متغیر مرجع را به زیرکلاس ایجاد کنید.

اگر برنامه فوق را در نظر بگیرید، می‌توانید کلاس را به شکل زیر نمونه‌سازی کنید. اما با استفاده از متغیر مرجع کلاس پایه (در این مورد cal) نمی‌توانید به متد multiplication() که متعلق به زیرکلاس My_Calculation است، دسترسی داشته باشید.


Calculation demo = new My_Calculation();
demo.addition(a, b);
demo.Subtraction(a, b);

توجه − یک زیرکلاس همه اعضا (فیلدها، متدها و کلاس‌های تو در تو) را از کلاس پایه خود به ارث می‌برد. سازنده‌ها عضو نیستند، بنابراین توسط زیرکلاس به ارث نمی‌برند، اما می‌توان سازنده کلاس پایه را از زیرکلاس فراخوانی کرد.

کلمه کلیدی super

کلمه کلیدی super مشابه کلمه کلیدی this است. در زیر شرایطی استفاده می‌شود:

  • اگر بخواهیم اعضای کلاس پایه را از اعضای زیرکلاس تمییز دهیم، اگر نامشان یکسان باشد.

  • از آن برای فراخوانی سازنده کلاس پایه از زیرکلاس استفاده می‌شود.

تمایز اعضا

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


super.variable
super.method();

کد نمونه

در این بخش، یک برنامه ارائه شده است که استفاده از کلمه کلیدی super را نشان می‌دهد.

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

کد را در یک فایل با نام Sub_class.java کپی و پیست کنید.

نمونه


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();
   }
}

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


javac Super_Demo
java Super

با اجرای برنامه، نتیجه زیر را دریافت خواهید کرد −

خروجی


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

h2>فراخوانی سازنده کلاس پایه

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


super(values);

کد نمونه

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

کد زیر را در یک فایل با نام Subclass.java کپی و پیست کنید

نمونه


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 args[]) {
      Subclass s = new Subclass(24);
      s.getAge();
   }
}

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


javac Subclass
java Subclass

با اجرای برنامه، نتیجه زیر را دریافت خواهید کرد −

خروجی


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 {
}

حالا، براساس مثال بالا، در اصطلاحات شیء-گرا، موارد زیر درست هستند −

  • Animal (حیوان)، کلاسی بالادستی برای کلاس Mammal (ثدی) است.
  • Animal (حیوان)، کلاسی بالادستی برای کلاس Reptile (خزنده) است.
  • Mammal (ثدی) و Reptile (خزنده)، زیرکلاس‌های کلاس Animal (حیوان) هستند.
  • Dog (سگ)، زیرکلاسی برای هر دو کلاس Mammal (ثدی) و Animal (حیوان) است.

حالا، اگر رابطه IS-A را در نظر بگیریم، می‌توانیم بگوییم −

  • Mammal (ثدی) IS-A Animal (حیوان)
  • Reptile (خزنده) IS-A Animal (حیوان)
  • Dog (سگ) IS-A Mammal (ثدی)
  • بنابراین: Dog (سگ) همچنین IS-A Animal (حیوان) است

با استفاده از کلمه کلیدی extends، زیرکلاس‌ها قادر خواهند بود تمامی ویژگی‌های کلاس بالادستی را به جز ویژگی‌های خصوصی آن به ارث ببرند.

می‌توانیم با استفاده از عملگر instance، تضمین کنیم که Mammal (ثدی) در واقع یک Animal (حیوان) است.

Example (مثال)


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 با کلاس‌ها استفاده می‌شود تا ویژگی‌های یک رابط را به ارث ببرند. رابط‌ها هرگز توسط یک کلاس گسترش داده نمی‌شوند.

مثال


public interface Animal {
}

public class Mammal implements Animal {
}

public class Dog extends Mammal {
}

کلیدواژه instanceof

بیایید از اپراتور 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، ما نیازی به قرار دادن کل کدی که مربوط به سرعت است داخل کلاس Van نداریم، که این امکان را به ما می‌دهد تا کلاس Speed را در چندین برنامه مختلف استفاده کنیم.

در ویژگی مبتنی بر شیء‌گرایی، کاربران نیازی به مشغول شدن درباره کدام شیء کار واقعی را انجام می‌دهد ندارند. برای دستیابی به این هدف، کلاس Van جزئیات پیاده‌سازی را از کاربران کلاس Van پنهان می‌کند. بنابراین، در واقع اتفاقی که می‌افتد این است که کاربران از کلاس Van برای انجام یک عمل مشخص درخواست می‌دهند و کلاس Van یا خودش عمل را انجام می‌دهد یا از یک کلاس دیگر برای انجام عمل درخواست می‌کند.

انواع ارث‌بری

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

انواع ارث‌بری

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

مثال


public class extends Animal, Mammal{} 

با این حال، یک کلاس می‌تواند یک یا چند رابط را پیاده‌سازی کند، که به جاوا کمک کرده است تا از عدم امکان ارث‌بری چندگانه خلاص شود.