Customize Consent Preferences

We use cookies to help you navigate efficiently and perform certain functions. You will find detailed information about all cookies under each consent category below.

The cookies that are categorized as "Necessary" are stored on your browser as they are essential for enabling the basic functionalities of the site. ... 

Always Active

Necessary cookies are required to enable the basic features of this site, such as providing secure log-in or adjusting your consent preferences. These cookies do not store any personally identifiable data.

No cookies to display.

Functional cookies help perform certain functionalities like sharing the content of the website on social media platforms, collecting feedback, and other third-party features.

No cookies to display.

Analytical cookies are used to understand how visitors interact with the website. These cookies help provide information on metrics such as the number of visitors, bounce rate, traffic source, etc.

No cookies to display.

Performance cookies are used to understand and analyze the key performance indexes of the website which helps in delivering a better user experience for the visitors.

No cookies to display.

Advertisement cookies are used to provide visitors with customized advertisements based on the pages you visited previously and to analyze the effectiveness of the ad campaigns.

No cookies to display.

2.5 Εμφωλευμένες κλάσεις στην Java

Στην Java, ο όρος “εμφωλευμένες κλάσεις” αναφέρεται στη δυνατότητα να δημιουργήσουμε μια κλάση μέσα στο εσωτερικό μιας άλλης κλάσης. Αυτή η τεχνική ονομάζεται εμφωλευμένες κλάσεις ή εσωτερικές κλάσεις.

Οι εμφωλευμένες κλάσεις μας επιτρέπουν να οργανώσουμε τον κώδικά μας και να αυξήσουμε την ασφάλεια και τη συντήρηση του. Μια εμφωλευμένη κλάση έχει πρόσβαση σε όλα τα μέλη (μεταβλητές, μέθοδοι) της εξωτερικής κλάσης, συμπεριλαμβανομένων των ιδιωτικών μελών της.

Οι εμφωλευμένες κλάσεις μπορούν να χρησιμοποιηθούν για την οργάνωση του κώδικα, την υλοποίηση λειτουργικοτήτων που αφορούν μόνο την εξωτερική κλάση, και την επίτευξη μιας καθαρής και συμπαγούς δομής κώδικα.

Για να έχετε πρόσβαση στην εσωτερική κλάση, δημιουργήστε ένα αντικείμενο της εξωτερικής κλάσης και στη συνέχεια δημιουργήστε ένα αντικείμενο της εσωτερικής κλάσης:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// Αυτή είναι μια κλάση OuterClass
class OuterClass {
int x = 10;
// Αυτή είναι μια εσωτερική κλάση InnerClass
class InnerClass {
int y = 5;
}
}
public class Main {
public static void main(String[] args) {
OuterClass myOuter = new OuterClass(); // Δημιουργία αντικειμένου OuterClass
OuterClass.InnerClass myInner = myOuter.new InnerClass(); // Δημιουργία αντικειμένου InnerClass
System.out.println(myInner.y + myOuter.x); // Εμφάνιση της τιμής x και y
}
}
// Αυτή είναι μια κλάση OuterClass class OuterClass { int x = 10; // Αυτή είναι μια εσωτερική κλάση InnerClass class InnerClass { int y = 5; } } public class Main { public static void main(String[] args) { OuterClass myOuter = new OuterClass(); // Δημιουργία αντικειμένου OuterClass OuterClass.InnerClass myInner = myOuter.new InnerClass(); // Δημιουργία αντικειμένου InnerClass System.out.println(myInner.y + myOuter.x); // Εμφάνιση της τιμής x και y } }
// Αυτή είναι μια κλάση OuterClass
class OuterClass {
  int x = 10;

  // Αυτή είναι μια εσωτερική κλάση InnerClass
  class InnerClass {
    int y = 5;
  }
}

public class Main {
  public static void main(String[] args) {
    OuterClass myOuter = new OuterClass();  // Δημιουργία αντικειμένου OuterClass
    OuterClass.InnerClass myInner = myOuter.new InnerClass();  // Δημιουργία αντικειμένου InnerClass
    System.out.println(myInner.y + myOuter.x);  // Εμφάνιση της τιμής x και y
  }
}

Ο παραπάνω κώδικας δημιουργεί δύο κλάσεις, την OuterClass και την InnerClass. Η OuterClass είναι μια εξωτερική κλάση, ενώ η InnerClass είναι μια εσωτερική κλάση που βρίσκεται μέσα στην OuterClass.

Η OuterClass περιέχει ένα πεδίο x με τιμή 10. Η InnerClass περιέχει ένα πεδίο y με τιμή 5.

Στην Main κλάση, στην μέθοδο main, δημιουργείται ένα αντικείμενο myOuter της κλάσης OuterClass. Έπειτα, δημιουργείται ένα αντικείμενο myInner της κλάσης InnerClass μέσα από το myOuter αντικείμενο. Τελικά, εκτυπώνεται η τιμή του πεδίου y του myInner αντικειμένου προσθέτοντας την τιμή του πεδίου x του myOuter αντικειμένου.

Συνολικά, ο κώδικας εμφανίζει το αποτέλεσμα της πρόσθεσης των τιμών των πεδίων x και y, δηλαδή 15, στην οθόνη.

Εσωτερικές κλάσεις μπορούν να χρησιμοποιηθούν και για να κάνουν τον κώδικα πιο ασφαλή ή οργανωμένο. Ένα ακόμη παράδειγμα είναι η χρήση των private εσωτερικών κλάσεων για την προστασία ευαίσθητων δεδομένων από τις εξωτερικές κλάσεις.

Σε αντίθεση με μια “κανονική” κλάση, μια εσωτερική κλάση μπορεί να είναι ιδιωτική ή προστατευμένη. Αν δεν θέλετε αντικείμενα από το εξωτερικό να έχουν πρόσβαση στην εσωτερική κλάση, δηλώστε την κλάση ως ιδιωτική:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
class OuterClass {
int x = 10; // Μια μεταβλητή x στην εξωτερική κλάση OuterClass
private class InnerClass {
int y = 5; // Μια μεταβλητή y στην ιδιωτική εσωτερική κλάση InnerClass
}
}
public class Main {
public static void main(String[] args) {
OuterClass myOuter = new OuterClass();
// Δεν είναι δυνατή η δημιουργία αντικειμένου για την ιδιωτική εσωτερική κλάση
// OuterClass.InnerClass myInner = myOuter.new InnerClass();
}
}
class OuterClass { int x = 10; // Μια μεταβλητή x στην εξωτερική κλάση OuterClass private class InnerClass { int y = 5; // Μια μεταβλητή y στην ιδιωτική εσωτερική κλάση InnerClass } } public class Main { public static void main(String[] args) { OuterClass myOuter = new OuterClass(); // Δεν είναι δυνατή η δημιουργία αντικειμένου για την ιδιωτική εσωτερική κλάση // OuterClass.InnerClass myInner = myOuter.new InnerClass(); } }
class OuterClass {
  int x = 10; // Μια μεταβλητή x στην εξωτερική κλάση OuterClass

  private class InnerClass {
    int y = 5; // Μια μεταβλητή y στην ιδιωτική εσωτερική κλάση InnerClass
  }
}

public class Main {
  public static void main(String[] args) {
    OuterClass myOuter = new OuterClass();
    // Δεν είναι δυνατή η δημιουργία αντικειμένου για την ιδιωτική εσωτερική κλάση
    // OuterClass.InnerClass myInner = myOuter.new InnerClass();
  }
}

Ο παραπάνω κώδικας περιέχει δύο κλάσεις, την OuterClass και την Main. Ας τις αναλύσουμε μία προς μία:

  1. OuterClass: Αυτή η κλάση έχει ένα πεδίο x τύπου int με τιμή 10. Το πεδίο αυτό είναι προσβάσιμο από οποιαδήποτε μέθοδο της κλάσης OuterClass.
  2. Main: Αυτή η κλάση περιέχει τη μέθοδο main, η οποία είναι η εκκίνηση του προγράμματος. Μέσα στην main δημιουργείται ένα αντικείμενο της OuterClass με το όνομα myOuter.

Σημειώνεται ότι υπάρχει και η ιδιωτική εσωτερική κλάση InnerClass μέσα στην OuterClass, αλλά η προσπέλαση της δημιουργίας αντικειμένου αυτής της κλάσης από την Main κλάση έχει σχολιαστεί, δηλαδή έχει απενεργοποιηθεί με τη χρήση σχόλιων.

Αν προσπαθήσετε να έχετε πρόσβαση σε μια ιδιωτική εσωτερική κλάση από μια κλάση εκτός της θυγατρικής κλάσης, θα προκληθεί σφάλμα κατά τη διάρκεια του χρόνου εκτέλεσης (runtime error):

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
class OuterClass {
int x = 10;
private class InnerClass {
int y = 5;
}
}
public class Main {
public static void main(String[] args) {
OuterClass myOuter = new OuterClass();
// Δεν είναι δυνατή η δημιουργία αντικειμένου για την ιδιωτική εσωτερική κλάση
// OuterClass.InnerClass myInner = myOuter.new InnerClass();
}
}
class AnotherClass {
// Αυτό προκαλεί σφάλμα κατά τη διάρκεια της εκτέλεσης
// OuterClass.InnerClass myInner = new OuterClass().new InnerClass();
}
class OuterClass { int x = 10; private class InnerClass { int y = 5; } } public class Main { public static void main(String[] args) { OuterClass myOuter = new OuterClass(); // Δεν είναι δυνατή η δημιουργία αντικειμένου για την ιδιωτική εσωτερική κλάση // OuterClass.InnerClass myInner = myOuter.new InnerClass(); } } class AnotherClass { // Αυτό προκαλεί σφάλμα κατά τη διάρκεια της εκτέλεσης // OuterClass.InnerClass myInner = new OuterClass().new InnerClass(); }
class OuterClass {
  int x = 10;

  private class InnerClass {
    int y = 5;
  }
}

public class Main {
  public static void main(String[] args) {
    OuterClass myOuter = new OuterClass();
    // Δεν είναι δυνατή η δημιουργία αντικειμένου για την ιδιωτική εσωτερική κλάση
    // OuterClass.InnerClass myInner = myOuter.new InnerClass();
  }
}

class AnotherClass {
  // Αυτό προκαλεί σφάλμα κατά τη διάρκεια της εκτέλεσης
  // OuterClass.InnerClass myInner = new OuterClass().new InnerClass();
}

Στο παραπάνω παράδειγμα, η InnerClass είναι ιδιωτική και προσπαθούμε να δημιουργήσουμε ένα αντικείμενο της από μια άλλη κλάση. Αυτό θα προκαλέσει ένα runtime error.

Το σφάλμα που θα λάβετε στο προηγούμενο παράδειγμα είναι το εξής:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
The type OuterClass.InnerClass is not visible
at AnotherClass.<init>(AnotherClass.java:3)
at Main.main(Main.java:14)
Exception in thread "main" java.lang.Error: Unresolved compilation problem: The type OuterClass.InnerClass is not visible at AnotherClass.<init>(AnotherClass.java:3) at Main.main(Main.java:14)
Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
    The type OuterClass.InnerClass is not visible

    at AnotherClass.<init>(AnotherClass.java:3)
    at Main.main(Main.java:14)

Η αιτία του σφάλματος είναι ότι η ιδιωτική εσωτερική κλάση InnerClass δεν είναι ορατή από άλλες κλάσεις εκτός από την OuterClass.

Μια εσωτερική κλάση μπορεί επίσης να είναι στατική (static), το οποίο σημαίνει ότι μπορείτε να έχετε πρόσβαση σε αυτήν χωρίς να δημιουργήσετε ένα αντικείμενο της εξωτερικής κλάσης:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
class OuterClass {
int x = 10;
static class InnerClass {
int y = 5;
}
}
public class Main {
public static void main(String[] args) {
// Δεν χρειάζεται να δημιουργήσετε ένα αντικείμενο της εξωτερικής κλάσης για να έχετε πρόσβαση στη στατική εσωτερική κλάση
OuterClass.InnerClass myInner = new OuterClass.InnerClass();
System.out.println(myInner.y);
}
}
class OuterClass { int x = 10; static class InnerClass { int y = 5; } } public class Main { public static void main(String[] args) { // Δεν χρειάζεται να δημιουργήσετε ένα αντικείμενο της εξωτερικής κλάσης για να έχετε πρόσβαση στη στατική εσωτερική κλάση OuterClass.InnerClass myInner = new OuterClass.InnerClass(); System.out.println(myInner.y); } }
class OuterClass {
  int x = 10;

  static class InnerClass {
    int y = 5;
  }
}

public class Main {
  public static void main(String[] args) {
    // Δεν χρειάζεται να δημιουργήσετε ένα αντικείμενο της εξωτερικής κλάσης για να έχετε πρόσβαση στη στατική εσωτερική κλάση
    OuterClass.InnerClass myInner = new OuterClass.InnerClass();
    System.out.println(myInner.y);
  }
}

Στο παραπάνω παράδειγμα, η εσωτερική κλάση InnerClass είναι στατική. Αυτό σημαίνει ότι μπορείτε να έχετε πρόσβαση σε αυτήν χωρίς να χρειάζεται να δημιουργήσετε ένα αντικείμενο της εξωτερικής κλάσης OuterClass.

Ένα από τα πλεονεκτήματα των εσωτερικών κλάσεων είναι ότι μπορούν να έχουν πρόσβαση στα χαρακτηριστικά και τις μεθόδους της εξωτερικής κλάσης:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
class OuterClass {
int x = 10; // Μια μεταβλητή τύπου int με την τιμή 10
class InnerClass {
public int myInnerMethod() {
return x; // Επιστρέφει την τιμή της μεταβλητής x από την εξωτερική κλάση
}
}
}
public class Main {
public static void main(String[] args) {
OuterClass myOuter = new OuterClass(); // Δημιουργία ενός αντικειμένου της εξωτερικής κλάσης
OuterClass.InnerClass myInner = myOuter.new InnerClass(); // Δημιουργία ενός αντικειμένου της εσωτερικής κλάσης
System.out.println(myInner.myInnerMethod()); // Εκτύπωση της τιμής που επιστρέφει η μέθοδος myInnerMethod()
}
}
class OuterClass { int x = 10; // Μια μεταβλητή τύπου int με την τιμή 10 class InnerClass { public int myInnerMethod() { return x; // Επιστρέφει την τιμή της μεταβλητής x από την εξωτερική κλάση } } } public class Main { public static void main(String[] args) { OuterClass myOuter = new OuterClass(); // Δημιουργία ενός αντικειμένου της εξωτερικής κλάσης OuterClass.InnerClass myInner = myOuter.new InnerClass(); // Δημιουργία ενός αντικειμένου της εσωτερικής κλάσης System.out.println(myInner.myInnerMethod()); // Εκτύπωση της τιμής που επιστρέφει η μέθοδος myInnerMethod() } }
class OuterClass {
  int x = 10; // Μια μεταβλητή τύπου int με την τιμή 10

  class InnerClass {
    public int myInnerMethod() {
      return x; // Επιστρέφει την τιμή της μεταβλητής x από την εξωτερική κλάση
    }
  }
}

public class Main {
  public static void main(String[] args) {
    OuterClass myOuter = new OuterClass(); // Δημιουργία ενός αντικειμένου της εξωτερικής κλάσης
    OuterClass.InnerClass myInner = myOuter.new InnerClass(); // Δημιουργία ενός αντικειμένου της εσωτερικής κλάσης
    System.out.println(myInner.myInnerMethod()); // Εκτύπωση της τιμής που επιστρέφει η μέθοδος myInnerMethod()
  }
}

Στο παραπάνω παράδειγμα, η εσωτερική κλάση InnerClass έχει πρόσβαση στη μεταβλητή x της εξωτερικής κλάσης OuterClass. Μέσω της δημιουργίας ενός αντικειμένου της OuterClass και του ακόλουθου δημιουργίας ενός αντικειμένου της InnerClass, μπορούμε να καλέσουμε τη μέθοδο myInnerMethod() και να επιστρέψουμε την τιμή της μεταβλητής x.

Το παραπάνω παράδειγμα θα εμφανίσει το ακόλουθο αποτέλεσμα:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
10
10
10

Στη μέθοδο main(), δημιουργούμε ένα αντικείμενο της OuterClass και ένα αντικείμενο της InnerClass. Στη συνέχεια, καλούμε τη μέθοδο myInnerMethod() στο αντικείμενο της InnerClass, η οποία επιστρέφει την τιμή της μεταβλητής x της εξωτερικής κλάσης. Τέλος, εκτυπώνουμε την τιμή που επιστρέφει η μέθοδος myInnerMethod(), η οποία είναι 10.

14 Ιουνίου, 2023
top
error: Content is protected !!
Μετάβαση σε γραμμή εργαλείων