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

כיתות פנימיות של ג'אווה

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

כיתות מקוננות ופנימיות

אז כל הכיתות שנמצאות בתוך מחלקות אחרות נקראות מחלקות מקוננות.
class OuterClass {
    ...
    class NestedClass {
        ...
    }
}
מחלקות מקוננות שאינן סטטיות נקראות מחלקות פנימיות , ואלו שהן סטטיות נקראות מחלקות מקוננות סטטיות . כיתות פנימיות של Java - 1
class OuterClass {
    ...
    static class StaticNestedClass {
        ...
    }
    class InnerClass {
        ...
    }
}
לפיכך, כל הכיתות הפנימיות מקוננות, אך לא כל המקוננות הן פנימיות. אלו ההגדרות העיקריות. כיתות פנימיות הן מעין מנגנון אבטחה בג'אווה. אנו יודעים שלא ניתן לשייך מחלקה רגילה למשנה גישה פרטית. עם זאת, אם הכיתה שלנו היא חברה בכיתה אחרת, אז ניתן להפוך את הכיתה הפנימית לפרטית. תכונה זו משמשת גם לגישה לחברי כיתה פרטיים.

דוגמה לכיתה פנימית

אז בואו ננסה ליצור מחלקה כלשהי, ובתוכה - מחלקה נוספת. תארו לעצמכם סוג של קונסולת משחקים מודולרית. יש "קופסה" עצמה, וניתן לחבר אליה מודולים מסוימים. לדוגמה, בקר משחק, הגה, קסדת VR, אשר, ככלל, לא עובדים ללא הקונסולה עצמה. כאן יש לנו את מחלקת GameConsole. יש לו 2 שדות ושיטה אחת - start() . ההבדל בין GameCosole למחלקה שאנו רגילים אליה הוא שיש לה מחלקה פנימית של GameController .
public class GameConsole {
    private String model;
    private int weight;

    public void run() {
        System.out.println("Game console is on");
    }


    public class GameController {

        private String color;

        public void start() {
            System.out.println("start button is pressed");
        }

        public void x() {
            System.out.println("x button is pressed");
        }

        public void y() {
            System.out.println("y button is pressed");
        }
        public void a() {
            System.out.println("a button is pressed");
        }

        public void b() {
            System.out.println("b button is pressed");
        }
        public void mover() {
            System.out.println("mover button is pressed");
        }

    }

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

   public static void main(String[] args) {
       GameController controller = new GameController();
       controller.x();
   }
}
מה שקורה במקרה זה לא ברור, מכיוון שהבקר עצמו לא עובד ללא קונסולה. יצרנו אובייקט של קונסולת משחקים. יצרנו את המשנה שלו - בקר המשחק. ועכשיו אנחנו יכולים לשחק, פשוט הקש על המקשים הנכונים. השיטות שאנו צריכים נקראות על האובייקטים הנכונים. הכל פשוט ונוח. בדוגמה זו, חילוץ בקר המשחק משפר את האנקפסולציה (אנחנו מסתירים את הפרטים של חלקי הקונסולה בתוך המחלקה המקבילה), ומאפשר הפשטה מפורטת יותר. אבל אם ניצור, למשל, תוכנית המדמה חנות שבה ניתן לקנות בנפרד קסדת VR או בקר, הדוגמה הזו תיכשל. שם עדיף ליצור בקר משחק בנפרד. ניקח דוגמה נוספת. הזכרנו למעלה שאנחנו יכולים להפוך את המעמד הפנימי לפרטי ועדיין לקרוא לו מהמעמד החיצוני. להלן דוגמה לשיעורים כאלה.
class OuterClass {

   // inner class
   private class InnerClass {
       public void print() {
           System.out.println("We are in the inner class...");
       }
   }

   // method of outer class. We are create an inner class from the method of outer one
   void display() {
       InnerClass inner = new InnerClass();
       inner.print();
   }
}
כאן ה- OuterClass הוא המחלקה החיצונית, InnerClass היא המחלקה הפנימית, display() היא השיטה שבתוכה אנו יוצרים אובייקט של המחלקה הפנימית. כעת בוא נכתוב מחלקת הדגמה עם שיטה עיקרית שבה אנו הולכים להפעיל את המתודה display() .
public class OuterDemoMain {

       public static void main(String args[]) {
           // create an object of the outer class
           OuterDemo outer = new OuterDemo();

           outer.display();
       }
}
אם תפעיל תוכנית זו, תקבל את התוצאה הבאה:
אנחנו במעמד הפנימי...

סיווג כיתות פנימיות

המחלקות הפנימיות עצמן או המחלקות הלא סטטיות המקוננות מתחלקות לשלוש קבוצות.
  • מעמד פנימי כמו שהוא. רק מחלקה אחת לא סטטית בתוך השנייה, כפי שהדגמנו למעלה עם דוגמה של GameConsole ו- GameController .
  • מחלקה פנימית-שיטה מקומית היא מחלקה בתוך מתודה.
  • כיתה פנימית אנונימית.
כיתות פנימיות של Java - 2

כיתה פנימית מקומית בשיטה

בג'אווה אפשר לכתוב מחלקה בתוך מתודה וזה סוג מקומי. כמו משתנים מקומיים, ההיקף של מחלקה פנימית מוגבל בתוך מתודה. ניתן ליצור מחלקה פנימית-מתודה מקומית רק בתוך השיטה שבה מוגדרת המחלקה הפנימית. בואו נדגים כיצד להשתמש במחלקה הפנימית של השיטה המקומית.
public class OuterDemo2 {

   //instance method of the outer class OuterDemo2
   void myMethod() {
       String str = "and it's a value from OuterDemo2 class' myMethod ";

       // method-local inner class
       class methodInnerDemo {
           public void print() {
               System.out.println("Here we've got a method inner class... " );
               System.out.println(str);

           }
       }

       // Access to the inner class
       methodInnerDemo inn = new methodInnerDemo();
       inn.print();
   }
}
עכשיו אנחנו הולכים לכתוב מחלקת הדגמה עם שיטה ראשית שבה אנחנו הולכים להפעיל את המתודה outer() .
public class OuterDemoMain {


   public static void main(String args[]) {
       OuterDemo2 outer = new OuterDemo2();
       outer.myMethod();
   }
}
הפלט הוא:
כאן יש לנו מחלקה פנימית של שיטה... וזה ערך מ-myMethod של OuterDemo2 class'

מעמד פנימי אנונימי

כיתה פנימית המוצהרת ללא שם כיתה נקראת כיתה פנימית אנונימית. כאשר אנו מכריזים על מעמד פנימי אנונימי, אנו מייצרים אותו מיד. בדרך כלל, מחלקות כאלה משמשות בכל פעם שאתה צריך לעקוף מחלקה או שיטת ממשק.
abstract class OuterDemo3 {
   public abstract void method();

}
   class outerClass {

       public static void main(String args[]) {
           OuterDemo3 inner = new OuterDemo3() {
               public void method() {
                   System.out.println("Here we've got an example of an  anonymous inner class");
               }
           };
           inner.method();
       }
   }
הפלט נמצא כאן:
הנה יש לנו דוגמה לכיתה פנימית אנונימית...

מעמד פנימי אנונימי כטיעון

ניתן גם להעביר כיתה פנימית אנונימית כטיעון לשיטה. הנה דוגמא.
interface OuterDemo4 {
       String hello();
   }

   class NewClass {
       // accepts the object of interface
       public void displayMessage(OuterDemo4 myMessage) {
           System.out.println(myMessage.hello());
           System.out.println("example of anonymous inner class as an argument");
       }

       public static void main(String args[]) {
           NewClass newClass = new NewClass();

           //here we pass an anonymous inner class as an argument
           newClass.displayMessage(new OuterDemo4() {
               public String hello() {
                   return "Hello!";
               }
           });
       }
}
הפלט נמצא כאן:
שלום! דוגמה למעמד פנימי אנונימי כטיעון
כדי לחזק את מה שלמדת, אנו מציעים לך לצפות בשיעור וידאו מקורס Java שלנו
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION