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

מופע וירושה בג'אווה

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

יְרוּשָׁה

אז מהי ירושה? instanceof ו-Inheritance 101 - 1 Inheritance הוא מנגנון תכנות (כולל ב-Java) המאפשר להכריז על מחלקה חדשה על סמך מחלקה קיימת. המחלקה הנגזרת מקבלת גישה לשדות ולשיטות של מחלקת האב. למה שנצטרך את זה? ובכן, תאר לעצמך שאתה צריך ליצור מספר מחלקות רכב בתוכנית: משאית, RaceCar, Sedan, Pickup וכו'. עוד לפני כתיבת קוד כלשהו, ​​אתה יודע בוודאות שלכל המחלקות הללו יש הרבה במשותף: לכל המכוניות יש דגם שם, שנת ייצור, גודל מנוע, מהירות מרבית וכו' (שלא לדבר על העובדה שלכולם יש גלגלים וחלקים אחרים במשותף). במצב זה, אתה יכול:
  • צור שדות אלה בכל מחלקה (הוספת אותם לכל מחלקה חדשה של מכוניות תוך כדי יצירתה)
  • הבא את השדות המשותפים לכל המכוניות למחלקה Carאב, ולאחר מכן השתמש במילת המפתח extends כדי לגזור את כל המחלקות לסוגים ספציפיים של מכוניות מהמחלקה Car.
באופן טבעי, האפשרות השנייה היא הרבה יותר נוחה:
public class Car {

   private String model;
   private int maxSpeed;
   private int yearOfManufacture;

   public Car(String model, int maxSpeed, int yearOfManufacture) {
       this.model = model;
       this.maxSpeed = maxSpeed;
       this.yearOfManufacture = yearOfManufacture;
   }
}

public class Truck extends Car {

   public Truck(String model, int maxSpeed, int yearOfManufacture) {
       super(model, maxSpeed, yearOfManufacture);
   }
}

public class Sedan extends Car {
   public Sedan(String model, int maxSpeed, int yearOfManufacture) {
       super(model, maxSpeed, yearOfManufacture);
   }
}
לכל הפחות, אנו נמנעים משכפול מיותר של קוד (ועלינו לשאוף לכך תמיד בעת כתיבת תוכניות). בנוסף, יש לנו מבנה מחלקה פשוט ומובן, כאשר כל התחומים המשותפים לכל המכוניות מאוחדים למחלקה אחת. אם למשאיות יש תחומים מיוחדים שאין למכוניות אחרות, ניתן להכריז עליהם בכיתה Truck. כך גם לגבי שיטות. לכל המכוניות יש התנהגות משותפת מסוימת שניתן לתאר באמצעות שיטות, למשל התנעת המכונית, האצה/בלימה וכו'. ניתן לאחד את השיטות הנפוצות הללו למחלקת האב, וכל סוג ספציפי של Carמכונית יכול להגדיר את הפעולות הייחודיות שלה במחלקות הנגזרות שלהן .
public class Car {

   public void gas() {
       // Accelerate
   }

   public void brake() {
       // Brake
   }
}


public class F1Car extends Car {

   public void pitStop() {

       // Only race cars make pit stops
   }

   public static void main(String[] args) {

       F1Car formula1Car = new F1Car();
       formula1Car.gas();
       formula1Car.pitStop();
       formula1Car.brake();
   }
}
הוספנו לכיתה את השיטות המשותפות לכל המכוניות Car. אבל, תסתכל על F1Carהמעמד, המייצג מכוניות מרוץ "פורמולה 1". עצירות פיט (עצירות לתחזוקה דחופה של מכונית) נעשות רק במרוצים, אז הוספנו את הפונקציונליות הספציפית הזו למחלקה הנגזרת הרלוונטית. instanceof ו-Inheritance 101 - 2

מופע של מפעיל

ב-Java, יש אופרטור מיוחד, instanceof , לבדיקה אם אובייקט נוצר על סמך מחלקה מסוימת. זה מחזיר נכון או לא נכון בהתאם לתוצאה של הבדיקה. בוא נראה איך זה עובד באמצעות השיעורים בדוגמה המכונית שלנו:
public class Truck extends Car {

   public static void main(String[] args) {

       Truck truck = new Truck();
       System.out.println(truck instanceof Car);
   }
}
פלט: true האופרטור instanceofמחזיר true , מכיוון שיש לנו Truckאובייקט, וכל המשאיות הן מכוניות. הכיתה Truckנגזרת מהכיתה Car. כל המשאיות נוצרות על בסיס ההורה המשותף, Carהכיתה. תסתכל מקרוב על אופן instanceofהשימוש באופרטור. אתה כותב את זה בלי נקודה, מכיוון שזה אופרטור, לא שיטה ("מופע אובייקט של מחלקה"). בוא ננסה דרך אחרת:
public static void main(String[] args) {

   Car car = new Car();
   System.out.println(car instanceof Truck);
}
פלט: false המחלקה Car(ואובייקטי המכונית) אינם נובעים מהמחלקה Truck. כל המשאיות הן מכוניות, אבל לא כל המכוניות הן משאיות. Carאובייקטים אינם מבוססים על Truckהמחלקה. עוד דוגמה אחת:
public static void main(String[] args) {

   Car car = new Car();
   Truck truck = new Truck();
   System.out.println(car instanceof Object && truck instanceof Object);
}
פלט: נכון גם כאן ההיגיון פשוט: כל המחלקות ב-Java, כולל המחלקות שאתה יוצר, יורדות מהמחלקה Object(למרות שאינך כותב "extends Object" - זה כבר מרומז). איך ומתי זה יהיה שימושי? האופרטור instanceofמשמש לרוב בעת עקיפת equals()השיטה. לדוגמה, כך equalsמיושמת השיטה במחלקה String:
public boolean equals(Object anObject) {
   if (this == anObject) {
       return true;
   }
   if (anObject instanceof String) {
       String anotherString = (String) anObject;
       int n = value.length;
       if (n == anotherString.value.length) {
           char v1[] = value;
           char v2[] = anotherString.value;
           int i = 0;
           while (n-- != 0) {
               if (v1[i] != v2[i])
                       return false;
               i++;
           }
           return true;
       }
   }
   return false;
}
לפני השוואה בין a Stringלאובייקט שעבר, השיטה בודקת אם האובייקט הוא אפילו מחרוזת? רק אז הוא מתחיל להשוות את המאפיינים של שני האובייקטים. אם הבדיקה הזו לא הייתה קיימת, ניתן היה להעביר כל אובייקט עם שדות ערך ואורך למתודה ולהשוות עם String, וזה יהיה שגוי, כמובן.
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION