JavaRush /בלוג Java /Random-HE /מופע של אופרטור ב-Java

מופע של אופרטור ב-Java

פורסם בקבוצה
שלום! היום נדבר על המופע של האופרטור, נסתכל על דוגמאות לשימוש בו ונגע בכמה נקודות הקשורות לפעולתו :) ברמות המוקדמות של JavaRush, כבר נתקלת באופרטור הזה. אתה זוכר למה זה נחוץ? אם לא, זה לא משנה, בואו נזכור ביחד. יש צורך ב-instanceof אופרטור כדי לבדוק אם האובייקט שאליו המשתנה X מפנה נוצר ממחלקה Y כלשהי. נשמע פשוט. למה חזרנו לנושא הזה? קודם כל, כי עכשיו אתה מכיר היטב את מנגנון ההורשה בג'אווה ועקרונות אחרים של OOP. הנושא של instanceof יהיה הרבה יותר ברור ונבחן מקרי שימוש מתקדמים יותר. ללכת! כיצד פועל האופרטור Instanceof - 1אתה בטח זוכר שהאופרטור instanceof מחזיר אמת אם הבדיקה הייתה אמת, או שקר אם התוצאה הייתה שקר. כתוצאה מכך, הוא נמצא לרוב בסוגים שונים של תנאי בדיקה ( if…else). נתחיל עם דוגמאות פשוטות יותר:
public class Main {

   public static void main(String[] args) {

       Integer x = new Integer(22);

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

   public static void main(String[] args) {

       Integer x = new Integer(22);

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

}

public class Cat extends Animal {

}

public class MaineCoon extends Cat {

}
אנחנו כבר יודעים איך instanceof מתנהג כשאנחנו בודקים אם חפץ שייך לכיתה במצב רגיל, אבל מה קורה אם נוסיף כאן מערכת יחסים הורה-ילד? כיצד פועל האופרטור Instanceof - 2 לדוגמה, מה לדעתך תניב הבדיקה הבאה:
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 מפענח את המושג "אובייקט שנוצר על סמך מחלקה"? כתוצאה מכך, קיבלנו את זה Сat instanceof Animal == true, אבל אפשר למצוא פגם בניסוח כזה. מדוע האובייקט הזה Catנוצר על סמך המחלקה Animal? האם זה לא נוצר רק על סמך המעמד שלו? התשובה די פשוטה, ואולי כבר הבנתם אותה. זכור את הסדר שבו נקראים בנאים והמשתנים מאותחלים בעת יצירת אובייקט. כבר כיסינו את הנושא הזה במאמר על בנאי המחלקה . הנה דוגמה מההרצאה ההיא:
public class Animal {

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

   public static int animalCount = 7700000;

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

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

class Cat extends Animal {

   String tail = "The initial value of tail in the Cat class";

   static int catsCount = 37;

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

   public static void main(String[] args) {
       Cat cat = new Cat("Brain", "Heart", "Tail");
   }
}
ואם תפעיל אותו ב-IDE, הפלט של המסוף ייראה כך: הקונסטרוקטור של מחלקת הבסיס Animal פועל האם המשתנים של המחלקה Animal כבר אותחלו? ערך נוכחי של המשתנה הסטטי animalCount = 7700000 ערך נוכחי של מוח במחלקה Animal = ערך התחלתי של מוח במחלקת Animal ערך נוכחי של לב במחלקת Animal = ערך התחלתי של לב במחלקת Animal הבנאי של מחלקת הבסיס Animal סיים את עבודתו! ערך נוכחי של מוח = מוח ערך נוכחי של לב = לב הבנאי של מחלקת החתול התחיל לעבוד (בנאי החיות כבר הופעל) ערך נוכחי של המשתנה הסטטי catsCount = 37 ערך נוכחי של זנב = ערך התחלתי של זנב ב- כיתה חתול ערך נוכחי של זנב = זנב אתה זוכר עכשיו? :) בנאי מחלקות הבסיס, אם יש כזה, נקרא תמיד ראשון בעת ​​יצירת אובייקט כלשהו. Instanceof פועל לפי עיקרון זה כאשר הוא מנסה לקבוע אם אובייקט נוצר Аממחלקה Б. אם נקרא בנאי מחלקות הבסיס, אז לא יכול להיות ספק. עם הסימון השני הכל פשוט יותר:
System.out.println(cat instanceof MaineCoon);
הבנאי MaineCoonלא נקרא בעת יצירת Cat, וזה הגיוני. אחרי הכל, MaineCoonהוא צאצא Cat, לא אב קדמון. אבל Catזה לא תבנית עבור. אוקיי, זה נראה ברור. מה יקרה אם נעשה את זה:
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);
מה instanceof יבדוק: משתנה המחלקה שלנו Catאו אובייקט המחלקה שלנו MaineCoon? למעשה, התשובה לשאלה זו פשוטה. אתה רק צריך לקרוא שוב את ההגדרה של האופרטור שלנו: יש צורך באופרטור instanceof כדי לבדוק אם האובייקט שאליו המשתנה מתייחס נוצר Xעל סמך מחלקה כלשהי Y. האופרטור instanceof בודק את המקור של אובייקט, לא משתנה. לכן, בדוגמה, בשתי הפעמים זה יציג true במסוף : יש לנו אובייקט מסוג MaineCoon. באופן טבעי, הוא נוצר על סמך הכיתה MaineCoon, אבל גם על סמך כיתת האב Cat!
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION