Sobes.tech
Middle

Ποιοι τύποι εσωτερικών κλάσεων υπάρχουν;

sobes.tech AI

Απάντηση από AI

Οι εσωτερικές κλάσεις (Nested Classes) στη Java χωρίζονται σε δύο βασικούς τύπους:

  1. Στατικές εσωτερικές κλάσεις (Static Nested Classes)

    • Επισημαίνονται με τον τροποποιητή static.
    • Συμπεριφέρονται όπως κανονικά στατικά μέλη της κλάσης-δοχείου.
    • Μπορούν να έχουν πρόσβαση στα στατικά μέλη της εξωτερικής κλάσης (ακόμα και αν είναι ιδιωτικά).
    • Δεν έχουν άμεση πρόσβαση στα μη-στατικά μέλη της εξωτερικής κλάσης.
    • Δημιουργούνται χωρίς ένα στιγμιότυπο της εξωτερικής κλάσης: OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();.
  2. Εσωτερικές κλάσεις (Inner Classes)

    Οι εσωτερικές κλάσεις δεν επισημαίνονται με static και σχετίζονται με ένα στιγμιότυπο της εξωτερικής κλάσης. Υπάρχουν υποκατηγορίες:

    • Μέλη-κλάσεις (Member Inner Classes)

      • Δηλώνονται σε επίπεδο μέλους της κλάσης-δοχείου, αλλά εκτός των μεθόδων της.
      • Έχουν πρόσβαση σε όλα τα μέλη της εξωτερικής κλάσης, συμπεριλαμβανομένων των ιδιωτικών.
      • Απαιτούν ένα στιγμιότυπο της εξωτερικής κλάσης για τη δημιουργία του δικού τους στιγμιότυπου: OuterClass outerObject = new OuterClass(); OuterClass.MemberInnerClass innerObject = outerObject.new MemberInnerClass();.
    • Τοπικές κλάσεις (Local Classes)

      • Δημιουργούνται μέσα σε μεθόδους, κατασκευαστές ή μπλοκ αρχικοποίησης.
      • Η ορατότητά τους περιορίζεται στο μπλοκ όπου δηλώνονται.
      • Δεν μπορούν να δηλωθούν με τροποποιητές πρόσβασης (public, private, protected).
      • Μπορούν να έχουν πρόσβαση σε τοπικές μεταβλητές final ή αποτελεσματικά final του εξωτερικού μπλοκ.
      • Δεν μπορούν να χρησιμοποιηθούν εκτός του μπλοκ όπου ορίζονται.
    • Ανώνυμες κλάσεις (Anonymous Classes)

      • Στην ουσία, είναι τοπικές κλάσεις χωρίς όνομα.
      • Δηλώνονται και δημιουργούνται ταυτόχρονα.
      • Χρησιμοποιούνται για την υλοποίηση μιας αφηρημένης κλάσης ή διεπαφής "στη στιγμή".
      • Όπως και οι τοπικές κλάσεις, έχουν πρόσβαση σε τοπικές μεταβλητές final ή αποτελεσματικά final του εξωτερικού μπλοκ.

    Παράδειγμα δομής:

class OuterClass {
    private int outerField;
    private static int staticOuterField;

    // Στατική εσωτερική κλάση
    static class StaticNestedClass {
        void accessOuter() {
            // Μπορεί να έχει πρόσβαση στα στατικά μέλη της εξωτερικής κλάσης
            int value = staticOuterField;
            // Δεν μπορεί να έχει πρόσβαση στα μη-στατικά μέλη της εξωτερικής κλάσης
            // int value2 = outerField; // Σφάλμα μεταγλώττισης
        }
    }

    // Μέλος-κλάση (Εσωτερική κλάση)
    class MemberInnerClass {
        void accessOuter() {
            // Μπορεί να έχει πρόσβαση σε όλα τα μέλη της εξωτερικής κλάσης
            int value1 = outerField;
            int value2 = staticOuterField;
        }
    }

    void methodWithLocalAndAnonymous() {
        final int localVar = 10; // αποτελεσματικά final

        // Τοπική κλάση
        class LocalClass {
            void accessOuter() {
                // Μπορεί να έχει πρόσβαση σε μέλη της εξωτερικής κλάσης και σε τοπικές μεταβλητές final/effectively final
                int value1 = outerField;
                int value2 = staticOuterField;
                int localValue = localVar;
            }
        }

        LocalClass localObj = new LocalClass();
        localObj.accessOuter();

        // Ανώνυμη κλάση (που υλοποιεί το interface Runnable)
        Runnable anonymousRunnable = new Runnable() {
            @Override
            public void run() {
                // Μπορεί να έχει πρόσβαση σε μέλη της εξωτερικής κλάσης και σε τοπικές μεταβλητές final/effectively final
                int value1 = outerField;
                int value2 = staticOuterField;
                int localValue = localVar;
                System.out.println("Running with local variable: " + localValue);
            }
        };

        anonymousRunnable.run();
    }
}