CodeGym /בלוג Java /Random-HE /ירושה בג'אווה
John Squirrels
רָמָה
San Francisco

ירושה בג'אווה

פורסם בקבוצה
Java היא שפה מונחה עצמים. זה אומר שכל דבר ב-Java מורכב ממחלקות והאובייקטים שלהם, ומציית לפרדיגמות של OOP (תכנות מונחה עצמים). פרדיגמה אחת כזו היא ירושה, מנגנון בג'אווה שבאמצעותו מחלקה אחת רשאית לרשת את התכונות (שדות ושיטות) של מחלקה אחרת. במילים פשוטות, ב-Java, ירושה פירושה יצירת מחלקות חדשות המבוססות על מחלקות קיימות. ירושה בג'אווה - 1

שחקנים מרכזיים של ירושה בג'אווה

  • ירושה היא התפיסה לפיה מחלקה יכולה לחזור באופן חלקי או מלא על המאפיינים והשיטות של האב שלה (המחלקה ממנה היא יורשת).
  • כיתת ילד, או תת-מחלקה, או מחלקה מורחבת, או מחלקה נגזרת היא מחלקה שיורשת מכיתה אחרת.
  • מחלקה אב, מחלקה על או מחלקה בסיס היא מחלקה שיש לה מספר פונקציות, ופונקציות אלו יכולות לעבור (לעבור בירושה) על ידי מחלקה אחרת (כיתה ילדה).
  • עקיפה של שיטה היא שינוי ההתנהגות של שיטת מחלקה נגזרת. זו בדרך כלל התנהגות יותר ספציפית ומעודנת. אם אתה מחליף שיטה ביורש שכבר נמצאת במחלקת האב, היא מעין מחליפה את שיטת האב.
  • לכיתה יכולה להיות רק כיתת אב אחת, אבל בכל כיתה יכולים להיות הרבה "ילדים".

איך זה עובד

שרשרת הירושה מכוונת מהמעמד המופשט ביותר למעמד הקונקרטי יותר. כלומר, מעמד העל הוא המופשט ביותר בשרשרת המעמדות. לעתים קרובות הוא מסומן כמופשט (מחלקה בסיסית שאינה דורשת יישום). כל השיעורים הנוספים ספציפיים יותר. לדוגמה, יש מחלקה בשם "גאדג'ט". זה יכול להיות בעל קיבולת סוללה של שדה (או מצב) "משקל", רמת טעינה בשטח ושיטות (או התנהגות) "עבודה" וטעינה. במקרה זה, שיטות יכולות להיות מופשטות, כלומר אין להן יישום ספציפי. אמנם אנחנו לא יכולים לומר איזה סוג של גאדג'ט זה, אבל זה בהחלט כל גאדג'ט נטען. בואו ניצור תת מחלקה טלפון של מחלקה גאדג'ט. זה כבר לא צריך להגדיר מחדש את המשקל והסוללה, הוא פשוט יורש אותם מהגאדג'ט המופשט. אבל יהיה צורך להבהיר את התנהגות העבודה. אתה יכול גם להוסיף שדות אחרים "אלכסון מסך", מחברים וכן הלאה. אתה יכול להוסיף שיטה חדשה "עדכן מערכת הפעלה". לאחר מכן, נוכל ליצור עוד שתי מחלקות ושניהם יעברו בירושה מטלפון, אנדרואיד ואייפון. שתי המחלקות יורשות את כל השדות והשיטות של הגאדג'ט והסמארטפון, וניתן לעקוף את השיטות. המחלקה הראשונה זקוקה לשדה "שם מותג", בעוד שהאייפון אינו זקוק לתחום זה, שכן רק חברה אחת מייצרת סמארטפונים כאלה.

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 {}
כיתת ילד יורשת את כל החברים הציבוריים והמוגנים בכיתת ההורים. זה לא משנה באיזו חבילה נמצאת תת-הכיתה. אם כיתת הילד נמצאת באותה חבילה כמו כיתת האב, היא גם יורשת את החברים הפרטיים של החבילה של ההורה. אתה יכול להשתמש באיברים שעברו בירושה כפי שהם, להחליף אותם, להסתיר אותם או להוסיף חברים חדשים:
  • אתה יכול להשתמש בשדות בירושה ישירות כמו כל שדה אחר.
  • אתה יכול להכריז על שדה בכיתת הילד שיש לו אותו שם כמו בכיתת האב. זה מסתיר את זה (אז עדיף לא לעשות את זה).
  • אתה יכול להכריז על שדות חדשים בכיתה הילד (כאלה שאין לכיתה האב).
  • ניתן להשתמש בשיטות שעברו בירושה ישירות בלי לעקוף במחלקה הנגזרת.
  • כמו כן, אתה יכול לכתוב שיטת מופע חדשה בתת-מחלקה בעלת חתימה זהה למתודה במחלקת האב. הליך זה עוקף אותו.
  • ניתן להצהיר על שיטות חדשות בכיתת הילד שלא הוכרזו בכיתת האב.
  • אתה יכול לכתוב בנאי תת-מחלקה שקורא לבנאי מחלקת העל או באופן מרומז או עם מילת המפתח העל.

דוגמא

בואו ניצור מחלקת 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...");
   }
}
לא ברור לחלוטין באיזה כלי נגינה מדובר ואיך לנגן בו. בואו ניצור כלי יותר ספציפי, כינור. יהיו לו אותם שדות כמו בכלי הנגינה (הם יקראו בקונסטרוקטור באמצעות מילת המפתח סופר. נוכל גם לעקוף את שיטת העבודה וליצור שיטה להגדרת מיתר כינור אחר מיתר.

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... הכינור מנגן
כלומר, אם יש שיטה דחוקה בכיתה הילד, אז שיטת האב לא תיקרא יותר. מה אם זה לא שם? כלומר, שיעור הכינור נראה כך:

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... הכלי מנגן...
כלומר, שיטת האב תקרא אוטומטית. אגב, ניתן להגדיר את כיתת הילד דרך האב הקדמון, כלומר לבצע העלאה:

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() של המחלקה הצאצאית תיקרא, אם היא קיימת.

היררכיית המעמדות של פלטפורמת Java

בג'אווה הכל מורכב משיעורים והם כפופים להיררכיה. נשאלת השאלה: האם יש מעמד שממנו כל האחרים עוברים בירושה? התשובה היא כן, אכן קיים מעמד כזה. וזה נקרא פשוט Object . המחלקה Object מחבילת java.lang, מגדירה ומיישמת התנהגות משותפת לכל המחלקות, כולל אלה שאתה יוצר. בפלטפורמת Java, מחלקות רבות נובעות ישירות מ- Object , מחלקות אחרות נובעות מחלק מהמחלקות הללו, וכן הלאה, יוצרות היררכיית מחלקות.

סוגי ירושה בג'אווה

בואו נדגיש כמה סוגי ירושה בג'אווה. 1. ירושה בודדת סוג זה הוא בדיוק כמו בדוגמה שלנו למעלה, תת-מחלקות יורשות את התכונות של מחלקה על אחת. בתמונה למטה, מחלקה A משמשת כמחלקה בסיס למחלקה הנגזרת B. 2. ירושה רב-שכבתית זו רק שרשרת של ירושה, כלומר יש מחלקה בסיסית A, מחלקה B עוברת ממנה בירושה ומחלקה C עובר בירושה מכיתה B. ב-Java, מחלקה לא יכולה לגשת ישירות לחברי הסבא והסבתא. 3. ירושה היררכית בירושה היררכית, מחלקה אחת משמשת כמחלקה על (מחלקה בסיס) ליותר מתת מחלקה אחת. למעלה, הבאנו דוגמה של כיתת טלפון, שבה יכולים להיות שני "ילדים" - אנדרואידפון ואייפון.

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