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

מופע Java של מפעיל

פורסם בקבוצה
היי! היום נדבר על המופע של האופרטור , נשקול דוגמאות לאופן השימוש בו, וניגע בכמה היבטים של אופן הפעולה שלו:) כבר נתקלת באופרטור הזה ברמות מוקדמות של CodeGym. אתה זוכר למה אנחנו צריכים את זה? אם לא, אל דאגה. בואו נזכור ביחד. יש צורך ב- instanceof אופרטור כדי לבדוק אם אובייקט שאליו משתנה X נוצר על סמך מחלקה Y כלשהי . זה נשמע פשוט. למה חזרנו לנושא הזה? קודם כל, כי עכשיו אתה מכיר היטב את מנגנון ההורשה של Java ואת שאר העקרונות של OOP. המופע של האופרטור יהיה עכשיו הרבה יותר ברור ואנו נראה דוגמאות מתקדמות יותר של אופן השימוש בו. בוא נלך! איך פועל המופע של האופרטור - 1אתה בוודאי זוכר שהאופרטור instanceof מחזיר אמת אם הבדיקה מוערכת כ-true, או false אם הביטוי הוא false. בהתאם לכך, זה מופיע בדרך כלל בכל מיני ביטויים מותנים ( אם...אחר ). נתחיל בכמה דוגמאות פשוטות יותר:
public class Main {

   public static void main(String[] args) {

       Integer x = new Integer(22);

       System.out.println(x instanceof Integer);
   }
}
מה לדעתך יוצג בקונסולה? ובכן, זה ברור כאן. :) אובייקט x הוא מספר שלם, אז התוצאה תהיה נכונה . פלט מסוף: נכון בוא ננסה לבדוק אם זה מחרוזת :
public class Main {

   public static void main(String[] args) {

       Integer x = new Integer(22);

       System.out.println(x instanceof String); // Error!
   }
}
קיבלנו שגיאה. ושימו לב: המהדר יצר את השגיאה לפני הפעלת הקוד! הוא ראה מיד שלא ניתן להמיר את מספר השלם והמחרוזת באופן אוטומטי אחד לשני ואינם קשורים באמצעות ירושה. כתוצאה מכך, אובייקט שלם אינו נוצר על סמך String . זה נוח ועוזר למנוע שגיאות זמן ריצה מוזרות, אז המהדר עזר לנו כאן :) כעת ננסה לשקול דוגמאות קשות יותר. מכיוון שהזכרנו ירושה, בואו נעבוד עם מערכת השיעורים הקטנה הבאה:
public class Animal {

}

public class Cat extends Animal {

}

public class MaineCoon extends Cat {

}
אנחנו כבר יודעים איך instanceof מתנהג כשאנחנו בודקים אם אובייקט הוא מופעים של כיתה, אבל מה קורה אם ניקח בחשבון את מערכת היחסים בין הורה לילד? לדוגמה, מה לדעתך יניבו הביטויים האלה:
public class Main {

   public static void main(String[] args) {

       Cat cat = new Cat();

       System.out.println(cat instanceof Animal);

       System.out.println(cat instanceof MaineCoon);

   }
}
פלט: נכון לא נכון השאלה העיקרית שצריך לענות עליה היא בדיוק איך instanceof מפרש 'אובייקט שנוצר על סמך מחלקה'? ' מופע חתול של בעלי חיים ' מוערך לנכון , אבל בוודאי נוכל למצוא פגם בניסוח הזה. מדוע נוצר אובייקט של חתול בהתבסס על המחלקה Animal ? האם הוא לא נוצר על סמך המעמד שלו בלבד? התשובה פשוטה מספיק, ואולי כבר חשבת עליה. זכור את הסדר שבו נקראים בנאים והמשתנים מאותחלים בעת יצירת אובייקט. כבר כיסינו את הנושא הזה במאמר על בנאי מחלקות . הנה דוגמה מהשיעור ההוא:
public class Animal {

   String brain = "Initial value of brain in the Animal class";
   String heart = "Initial value of heart in the Animal class";

   public static int animalCount = 7700000;

   public Animal(String brain, String heart) {
       System.out.println("Animal base class constructor is running");
       System.out.println("Have the variables of the Animal class already been initialized?");
       System.out.println("Current value of static variable animalCount = " + animalCount);
       System.out.println("Current value of brain in the Animal class = " + this.brain);
       System.out.println("Current value of heart in the Animal class = " + this.heart);
       System.out.println("Have the variables of the Cat class already been initialized?");
       System.out.println("Current value of static variable catCount = " + Cat.catCount);

       this.brain = brain;
       this.heart = heart;
       System.out.println("Animal base class constructor is done!");
       System.out.println("Current value of brain = " + this.brain);
       System.out.println("Current value of heart = " + this.heart);
   }
}

public class Cat extends Animal {

   String tail = "Initial value of tail in the Cat class";

   static int catCount = 37;

   public Cat(String brain, String heart, String tail) {
       super(brain, heart);
       System.out.println("The Cat class constructor has started (The Animal constructor already finished)");
       System.out.println("Current value of static variable catCount = " + catCount);
       System.out.println("Current value of tail = " + this.tail);
       this.tail = tail;
       System.out.println("Current value of tail = " + this.tail);
   }

   public static void main(String[] args) {
       Cat cat = new Cat("Brain", "Heart", "Tail");
   }
}
ואם אתה מפעיל את זה ב-IDE, הפלט של המסוף ייראה כך: בונה המחלקה של Animal base פועל האם המשתנים של המחלקה Animal כבר אותחלו? ערך נוכחי של משתנה סטטי animalCount = 7700000 ערך נוכחי של מוח במחלקה Animal = ערך התחלתי של מוח במחלקת Animal ערך נוכחי של לב במחלקת Animal = ערך התחלתי של לב במחלקת Animal יש כבר את המשתנים של מחלקת Cat אותחל? ערך נוכחי של משתנה סטטי catCount = 37 הבנאי מחלקות בסיס בעלי חיים נעשה! ערך נוכחי של מוח = מוח ערך נוכחי לב = לב בנאי מחלקת החתול התחיל (בנאי החיות כבר הסתיים) ערך נוכחי של משתנה סטטי catCount = 37 ערך נוכחי של זנב = ערך התחלתי של זנב במחלקה חתול ערך נוכחי של זנב = Tail Now אתה זוכר?:) הבנאי של מחלקת הבסיס, אם יש מחלקת בסיס, נקרא תמיד ראשון כשיוצרים אובייקט. המופע של האופרטור מונחה על ידי עיקרון זה כאשר הוא מנסה לקבוע אם אובייקט A נוצר על סמך מחלקה B. אם נקרא בנאי מחלקות הבסיס, אז לא יכול להיות ספק. עם הסימון השני, הכל פשוט יותר:
System.out.println(cat instanceof MaineCoon);
הבנאי MaineCoon לא נקרא כאשר אובייקט החתול נוצר, וזה הגיוני. אחרי הכל, מיין קון הוא צאצא של חתול , לא אב קדמון. וזה לא תבנית לחתול . בסדר, אני חושב שזה ברור לנו. אבל מה יקרה אם נעשה את זה?:
public class Main {

   public static void main(String[] args) {

       Cat cat = new MaineCoon();

       System.out.println(cat instanceof Cat);
       System.out.println(cat instanceof MaineCoon);


   }
}
הממ... עכשיו זה יותר קשה. בוא נדבר על זה. יש לנו משתנה Cat שאליו הקצינו אובייקט של MaineCoon . אגב, למה זה בכלל עובד? אנחנו יכולים לעשות את זה, נכון? כן אנחנו יכולים. אחרי הכל, כל מיין קון הוא חתול. אם זה לא לגמרי ברור, זכור את הדוגמה של טיפוסים פרימיטיביים מתרחבים:
public class Main {

   public static void main(String[] args) {

       long x = 1024;

   }
}
המספר 1024 הוא קצר : הוא משתלב בקלות במשתנה ארוך , מכיוון שיש מספיק בתים כדי להכיל אותו (זוכרים את הדוגמה עם הבובות?). תמיד ניתן להקצות אובייקט צאצא למשתנה קדמון. לעת עתה, רק זכור זאת, ובשיעורים הבאים ננתח כיצד זה עובד. אז מה מפיק הדוגמה שלנו?
Cat cat = new MaineCoon();
System.out.println(cat instanceof Cat);
System.out.println(cat instanceof MaineCoon);
מה יבדוק מופע ? המשתנה Cat שלנו או אובייקט MaineCoon שלנו ? התשובה היא שאלה זו היא למעשה פשוטה. אתה רק צריך לקרוא שוב את ההגדרה של האופרטור: יש צורך באופרטור instanceof כדי לבדוק אם אובייקט שאליו משתנה X נוצר על סמך מחלקה Y כלשהי . האופרטור instanceof בודק את המקור של אובייקט, לא את סוג המשתנה. לפיכך, בדוגמה זו, התוכנית שלנו תציג את האמת בשני המקרים: יש לנו אובייקט MaineCoon . ברור שהוא נוצר על סמך מחלקת MaineCoon , אבל הוא נוצר גם על סמך כיתת ההורים Cat !
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION