CodeGym /وبلاگ جاوا /Random-FA /وراثت در جاوا
John Squirrels
مرحله
San Francisco

وراثت در جاوا

در گروه منتشر شد
جاوا یک زبان شی گرا است. این بدان معنی است که همه چیز در جاوا از کلاس ها و اشیاء آنها تشکیل شده است و از پارادایم های OOP (برنامه نویسی شی گرا) تبعیت می کند. یکی از این پارادایم ها وراثت است، مکانیزمی در جاوا که به وسیله آن یک کلاس اجازه دارد ویژگی ها (فیلدها و روش ها) کلاس دیگر را به ارث ببرد. به زبان ساده، در جاوا، وراثت به معنای ایجاد کلاس های جدید بر اساس کلاس های موجود است. وراثت در جاوا - 1

عوامل کلیدی وراثت در جاوا

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

چگونه کار می کند

زنجیره وراثت از انتزاعی ترین کلاس به طبقه ملموس تر هدایت می شود. یعنی سوپرکلاس انتزاعی ترین در زنجیره طبقات است. اغلب به صورت انتزاعی (کلاس پایه که نیازی به پیاده سازی ندارد) نشان داده می شود. تمام کلاس های بعدی خاص تر هستند. به عنوان مثال، یک کلاس به نام "Gadget" وجود دارد. این می تواند ظرفیت باتری میدانی (یا حالت) "وزنی"، سطح شارژ میدانی و روش ها (یا رفتار) "کار" و شارژ داشته باشد. در این صورت روش ها می توانند انتزاعی باشند، یعنی پیاده سازی خاصی ندارند. در حالی که نمی‌توانیم بگوییم چه نوع ابزاری است، اما کاملاً هر ابزار قابل شارژی است. بیایید یک زیر کلاس Phone از کلاس Gadget ایجاد کنیم. دیگر نیازی به تعریف مجدد وزن و باتری ندارد، بلکه آنها را از ابزار انتزاعی به ارث می برد. اما رفتار کار باید روشن شود. همچنین می‌توانید فیلدهای دیگری «مورب صفحه»، رابط‌ها و غیره اضافه کنید. می توانید یک روش جدید "به روز رسانی سیستم عامل" را اضافه کنید. در مرحله بعد، می توانیم دو کلاس دیگر ایجاد کنیم و هر دو از Phone، Android و iPhone به ارث برده می شوند. هر دو کلاس تمام فیلدها و متدهای Gadget و Smartphone را به ارث می برند و متدها می توانند نادیده گرفته شوند. کلاس اول به یک فیلد "نام تجاری" نیاز دارد، در حالی که آیفون به این زمینه نیاز ندارد، زیرا تنها یک شرکت چنین گوشی های هوشمند را تولید می کند.

class Gadget {}
}
//subclass of Gadget class
class Phone extends Gadget {}
//subclass of Phone class
class IPhone extends Phone {}
//subclass of Phone class
class AndroidPhone extends Phone {}
یک کلاس فرزند همه اعضای عمومی و محافظت شده کلاس والد را به ارث می برد. فرقی نمی کند که کلاس فرعی در چه بسته ای باشد. اگر کلاس فرزند در همان بسته کلاس والد باشد، اعضای بسته-خصوصی والدین را نیز به ارث می برد. می توانید از اعضای ارثی استفاده کنید، آنها را جایگزین کنید، آنها را پنهان کنید یا اعضای جدید اضافه کنید:
  • شما می توانید از فیلدهای ارثی به طور مستقیم مانند هر فیلد دیگری استفاده کنید.
  • می توانید فیلدی را در کلاس فرزند اعلام کنید که همان نام کلاس والد است. آن را پنهان می کند (پس بهتر است این کار را نکنید).
  • می توانید فیلدهای جدیدی را در کلاس فرزند (فیلدهایی که کلاس والد ندارد) اعلام کنید.
  • روش‌های ارثی را می‌توان مستقیماً بدون overriding در کلاس مشتق شده استفاده کرد.
  • همچنین می توانید یک متد نمونه جدید در یک زیر کلاس بنویسید که دارای امضای مشابه متد در کلاس والد است. این رویه آن را نادیده می گیرد.
  • می‌توانید متدهای جدیدی را در کلاس فرزند اعلام کنید که در کلاس Parent اعلان نشده‌اند.
  • شما می توانید یک سازنده زیر کلاس بنویسید که سازنده سوپرکلاس را به صورت ضمنی یا با کلمه کلیدی super فراخوانی کند.

مثال

بیایید یک کلاس MusicalInstrument پایه با فیلدهای وزن و علامت تجاری و همچنین متد work() ایجاد کنیم . یک سازنده هم تعریف می کنیم.

public class MusicalInstrument {
   int weight;
   String tradeMark;

   public MusicalInstrument(int weight, String tradeMark) {
       this.weight = weight;
       this.tradeMark = tradeMark;
   }

   public void work() {
       System.out.println("the instrument is playing...");
   }
}
کاملاً مشخص نیست که چه نوع آلتی است و چگونه می توان آن را نواخت. بیایید یک ساز خاص تر، ویولن ایجاد کنیم. دارای همان فیلدهایی است که در ساز موسیقی وجود دارد (آنها در سازنده با استفاده از کلمه کلیدی super فراخوانی می شوند. همچنین می توانیم روش کار را نادیده بگیریم و روشی برای تنظیم سیم ویولن با سیم ایجاد کنیم.

public class Violin extends MusicalInstrument {
   String master;
   String owner;
   int age;
   boolean isTuned;

   public Violin(int weight, String tradeMark, String master, String owner, int age, boolean isTuned) {
       super(weight, tradeMark);
       this.master = master;
       this.owner = owner;
       this.age = age;
       this.isTuned = isTuned;
   }

   @Override
   public void work() {
       System.out.println("THe violin's playing");

   }

   public void violinTuning () {
     System.out.println("I'm tuning 1st string...");
     System.out.println("I'm tuning 2nd string...");
     System.out.println("I'm tuning 3rd string...");
     System.out.println("I'm tuning 4th string...");
}


}
بیایید یک کلاس دمو ایجاد کنیم تا کلاس ویولن را آزمایش کنیم و ببینیم وراثت دقیقا چگونه کار می کند.

public class InheritDemo {

   public static void main(String[] args) {

       Violin violin = new Violin(1, null, "Amati", "Kremer", 285, false);
       violin.violinTuning();
       violin.work();
   }
}
در این حالت خروجی برنامه به صورت زیر خواهد بود:
سیم 1 را کوک می کنم ... سیم 2 را کوک می کنم ... سیم 3 را کوک می کنم ... سیم 4 را کوک می کنم ... ویولن می نوازد
یعنی اگر یک متد overrid شده در کلاس فرزند وجود داشته باشد، دیگر متد ancestor فراخوانی نخواهد شد. اگه اونجا نباشه چی؟ یعنی کلاس ویولن به شکل زیر است:

public class Violin extends MusicalInstrument {
   String master;
   String owner;
   int age;
   boolean isTuned;

   public Violin(int weight, String tradeMark, String master, String owner, int age, boolean isTuned) {
       super(weight, tradeMark);
       this.master = master;
       this.owner = owner;
       this.age = age;
       this.isTuned = isTuned;
   }

  // @Override
 

 //  }

   public void violinTuning () {
       System.out.println("I'm tuning 1st string...");
       System.out.println("I'm tuning 2nd string...");
       System.out.println("I'm tuning 3rd string...");
       System.out.println("I'm tuning 4th string...");
   }

}
خروجی این است:
سیم 1 را می کوکم ... سیم 2 را می کوکم ... سیم 3 را کوک می کنم ... سیم 4 را کوک می کنم ... ساز می نوازد ...
یعنی متد ancestor به صورت خودکار فراخوانی می شود. به هر حال، کلاس فرزند را می توان از طریق جد تعریف کرد، یعنی برای انجام آپکست:

Parent parent = new Child()
این مقداردهی اولیه فقط برای دسترسی به اعضای موجود در کلاس والد و متدهای لغو شده استفاده می شود. در مثال ما این خواهد بود:

public class InheritDemo {

   public static void main(String[] args) {

       MusicalInstrument violin = new Violin(1, null, "Amati", "Kremer", 285, false);
       //violin.violinTuning();
       violin.work();
   }
}
در چنین حالتی، ما قادر به پیکربندی روش ویولن نیستیم. با این حال، در همان زمان، متد work() کلاس descendant در صورت وجود فراخوانی می شود.

سلسله مراتب کلاس پلتفرم جاوا

در جاوا، همه چیز از کلاس ها تشکیل شده است و آنها تابع یک سلسله مراتب هستند. این سوال مطرح می شود: آیا کلاسی وجود دارد که بقیه از آن به ارث برده شوند؟ پاسخ این است که بله، در واقع چنین کلاسی وجود دارد. و به سادگی Object نامیده می شود . کلاس Object از بسته java.lang، رفتار مشترک برای همه کلاس ها، از جمله کلاس هایی که شما ایجاد می کنید، تعریف و پیاده سازی می کند. در پلتفرم جاوا، بسیاری از کلاس‌ها مستقیماً از Object مشتق می‌شوند ، کلاس‌های دیگر از برخی از این کلاس‌ها سرچشمه می‌گیرند و به همین ترتیب، سلسله مراتب کلاس را تشکیل می‌دهند.

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

بیایید چند نوع وراثت در جاوا را برجسته کنیم. 1. Single Inheritance این نوع درست مانند مثال ما در بالا است، زیر کلاس ها ویژگی های یک کلاس فوق العاده را به ارث می برند. در تصویر زیر، کلاس A به عنوان یک کلاس پایه برای کلاس مشتق شده B عمل می کند. 2. وراثت چندسطحی این فقط یک زنجیره ارث بری است، یعنی یک کلاس پایه A وجود دارد، کلاس B از آن به ارث می رسد و کلاس C. از کلاس B به ارث رسیده است. در جاوا، یک کلاس نمی تواند مستقیماً به اعضای پدربزرگ و مادربزرگ دسترسی داشته باشد. 3. وراثت سلسله مراتبی در وراثت سلسله مراتبی، یک کلاس به عنوان یک کلاس فوق العاده (کلاس پایه) برای بیش از یک زیر کلاس عمل می کند. در بالا، مثالی از کلاس تلفن ارائه کردیم که می‌تواند دو «فرزند» داشته باشد - AndroidPhone و IPhone.

class A {
    public void printA() { 
System.out.println("A");
 }
}
  
class B extends A {
    public void printB() {
 System.out.println(" B"); }
}
  
class C extends A {
    public void printC() { 
System.out.println("C"); 
}
}
  
class D extends A {
    public void printD() { 
System.out.println("D");
 }
}
  
public class Demo {
    public static void main(String[] args)
    {
        B objB = new B();
        objB.printA();
        objB.printB();
  
        C objC = new C();
        objC.printA();
        objC.printC();
  
        D objD = new D();
        objD.printA();
        objD.printD();
    }
}
خروجی این است:
A B A C A D
4. وراثت چندگانه، یعنی وجود چندین اجداد ... اما صبر کنید، وراثت چندگانه کلاسیک در جاوا پشتیبانی نمی شود. تا حدودی، می توان آن را با استفاده از کلاس ها، بلکه رابط ها پیاده سازی کرد.

interface A {
   public void printA();
}

interface B {
   public void printB();
}

interface C extends A, B {
   public void print();
}
class InheritDemo implements C {
   @Override
   public void print()
   {
       System.out.println("Print something");
   }
  
   @Override
   public void printA() {      
   }

   @Override
   public void printB() {
   }
}
نظرات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION