2071 Stimmen

Java innere Klasse und statische verschachtelte Klasse

Was ist der Hauptunterschied zwischen einer inneren Klasse und einer statischen verschachtelten Klasse in Java? Spielt der Entwurf/die Implementierung eine Rolle bei der Wahl einer dieser beiden Klassen?

99 Stimmen

Die Antwort von Joshua Bloch ist in Leistungsfähiges Java lesen item 22 : Favor static member classes over non static

24 Stimmen

Für das Protokoll, es ist Punkt 24 in der 3. Auflage des gleichen Buches.

4voto

Pankti Punkte 411

Wenn wir eine statische Mitgliedsklasse innerhalb einer Klasse deklarieren, wird sie als verschachtelte Klasse der obersten Ebene oder als statische verschachtelte Klasse bezeichnet. Dies kann wie folgt demonstriert werden:

class Test{
    private static int x = 1;
        static class A{
        private static int y = 2;
        public static int getZ(){
            return B.z+x;
        }
    }
    static class B{
        private static int z = 3;
        public static int getY(){
            return A.y;
        }
    }
}

class TestDemo{
     public static void main(String[] args){
        Test t = new Test();
        System.out.println(Test.A.getZ());
        System.out.println(Test.B.getY());
    }
}

Wenn wir eine nicht-statische Mitgliedsklasse innerhalb einer Klasse deklarieren, wird sie als innere Klasse bezeichnet. Die innere Klasse kann wie folgt dargestellt werden:

    class Test{
        private int i = 10;
        class A{
            private int i =20;
            void display(){
            int i = 30;
            System.out.println(i);
            System.out.println(this.i);
            System.out.println(Test.this.i);
        }
    }
}

3voto

Pritam Banerjee Punkte 16396

Im Folgenden ein Beispiel für static nested class y inner class :

OuterClass.java

public class OuterClass {
     private String someVariable = "Non Static";

     private static String anotherStaticVariable = "Static";  

     OuterClass(){

     }

     //Nested classes are static
     static class StaticNestedClass{
        private static String privateStaticNestedClassVariable = "Private Static Nested Class Variable"; 

        //can access private variables declared in the outer class
        public static void getPrivateVariableofOuterClass(){
            System.out.println(anotherStaticVariable);
        }
     }

     //non static
     class InnerClass{

         //can access private variables of outer class
         public String getPrivateNonStaticVariableOfOuterClass(){
             return someVariable;
         }
     }

     public static void accessStaticClass(){
         //can access any variable declared inside the Static Nested Class 
         //even if it private
         String var = OuterClass.StaticNestedClass.privateStaticNestedClassVariable; 
         System.out.println(var);
     }

}

OuterClassTest:

public class OuterClassTest {
    public static void main(String[] args) {

        //access the Static Nested Class
        OuterClass.StaticNestedClass.getPrivateVariableofOuterClass();

        //test the private variable declared inside the static nested class
        OuterClass.accessStaticClass();
        /*
         * Inner Class Test
         * */

        //Declaration

        //first instantiate the outer class
        OuterClass outerClass = new OuterClass();

        //then instantiate the inner class
        OuterClass.InnerClass innerClassExample =  outerClass. new InnerClass();

        //test the non static private variable
        System.out.println(innerClassExample.getPrivateNonStaticVariableOfOuterClass()); 

    }

}

1voto

Mithun Debnath Punkte 520

Die Programmiersprache Java ermöglicht es Ihnen, eine Klasse innerhalb einer anderen Klasse zu definieren. Eine solche Klasse wird als verschachtelte Klasse bezeichnet und ist hier abgebildet:

class OuterClass {
...
class NestedClass {
    ...
    }
}

Verschachtelte Klassen werden in zwei Kategorien unterteilt: statische und nicht-statische. Verschachtelte Klassen, die als statisch deklariert sind, werden statische verschachtelte Klassen genannt. Nicht-statische verschachtelte Klassen werden als innere Klassen bezeichnet. Dabei ist zu beachten, dass nicht-statische verschachtelte Klassen (innere Klassen) Zugriff auf andere Mitglieder der umschließenden Klasse haben, auch wenn sie als privat deklariert sind. Statische verschachtelte Klassen haben nur Zugriff auf andere Mitglieder der umschließenden Klasse, wenn diese statisch sind. Auf nicht statische Mitglieder der äußeren Klasse kann sie nicht zugreifen. Wie bei Klassenmethoden und -variablen ist eine statische verschachtelte Klasse mit ihrer äußeren Klasse verbunden. Um zum Beispiel ein Objekt für die statische verschachtelte Klasse zu erstellen, verwenden Sie diese Syntax:

OuterClass.StaticNestedClass nestedObject =
 new OuterClass.StaticNestedClass(); 

Um eine innere Klasse zu instanziieren, müssen Sie zunächst die äußere Klasse instanziieren. Dann erstellen Sie das innere Objekt innerhalb des äußeren Objekts mit dieser Syntax:

OuterClass.InnerClass innerObject = new OuterClass().new InnerClass();

Warum wir verschachtelte Klassen verwenden

  1. Auf diese Weise lassen sich Klassen, die nur an einem Ort verwendet werden, logisch gruppieren.
  2. Sie erhöht die Verkapselung.
  3. Dies kann zu besser lesbarem und wartbarem Code führen.

Quelle: Die Java™-Tutorials - Verschachtelte Klassen

0voto

Sohi Punkte 414

Zunächst einmal gibt es keine solche Klasse namens Static class.The Static Modifikator Verwendung mit inneren Klasse (als Nested Class genannt) sagt, dass es ein statisches Mitglied der äußeren Klasse ist, was bedeutet, wir können es wie mit anderen statischen Mitgliedern zugreifen und ohne eine Instanz der äußeren Klasse. (Das ist der ursprüngliche Vorteil von static.)

Der Unterschied zwischen der Verwendung einer verschachtelten Klasse und einer normalen inneren Klasse ist:

OuterClass.InnerClass inner = new OuterClass().new InnerClass();

Zuerst können wir Outerclass instanziieren, dann können wir auf Inner zugreifen.

Aber wenn die Klasse verschachtelt ist, dann ist es die Syntax:

OuterClass.InnerClass inner = new OuterClass.InnerClass();

Dabei wird die statische Syntax als normale Implementierung des Schlüsselworts static verwendet.

0voto

JCvanDamme Punkte 569

Ein weiterer Anwendungsfall für verschachtelte Klassen, zusätzlich zu den bereits erwähnten, ist, wenn die verschachtelte Klasse Methoden hat, die nur von der äußeren Klasse aus zugänglich sein sollen. Dies ist möglich, weil die äußere Klasse Zugriff auf die privaten Konstruktoren, Felder und Methoden der verschachtelten Klasse hat.

Im folgenden Beispiel wird die Bank kann eine Bank.CreditCard die einen privaten Konstruktor hat, und kann das Limit einer Kreditkarte entsprechend der aktuellen Bankpolitik mit Hilfe des privaten setLimit(...) Fallmethode von Bank.CreditCard . (Ein direkter Feldzugriff auf die Instanzvariable limit würde auch in diesem Fall funktionieren). Von jeder anderen Klasse werden nur die öffentlichen Methoden von Bank.CreditCard zugänglich sind.

public class Bank {

    // maximum limit as per current bank policy
    // is subject to change
    private int maxLimit = 7000;

    // ------- PUBLIC METHODS ---------

    public CreditCard issueCard(
            final String firstName,
            final String lastName
    ) {
        final String number = this.generateNumber();
        final int expiryDate = this.generateExpiryDate();
        final int CVV = this.generateCVV();
        return new CreditCard(firstName, lastName, number, expiryDate, CVV);
    }

    public boolean setLimit(
            final CreditCard creditCard,
            final int limit
    ) {
        if (limit <= this.maxLimit) {    // check against current bank policy limit
            creditCard.setLimit(limit);  // access private method Bank.CreditCard.setLimit(int)
            return true;
        }
        return false;
    }

    // ------- PRIVATE METHODS ---------

    private String generateNumber() {
        return "1234-5678-9101-1123";   // the numbers should be unique for each card
    }

    private int generateExpiryDate() {
        return 202405;                  // date is YYYY=2024, MM=05
    }

    private int generateCVV() {
        return 123;                     // is in real-life less predictable
    }

    // ------- PUBLIC STATIC NESTED CLASS ---------

    public static final class CreditCard {
        private final String firstName;
        private final String lastName;
        private final String number;
        private final int expiryDate;
        private final int CVV;

        private int balance;
        private int limit = 100; // default limit

        // the constructor is final but is accessible from outer class
        private CreditCard(
                final String firstName,
                final String lastName,
                final String number,
                final int expiryDate,
                final int CVV
        ) {
            this.firstName = firstName;
            this.lastName = lastName;
            this.number = number;
            this.expiryDate = expiryDate;
            this.CVV = CVV;
        }

        // ------- PUBLIC METHODS ---------

        public String getFirstName() {
            return this.firstName;
        }

        public String getLastName() {
            return this.lastName;
        }

        public String getNumber() {
            return this.number;
        }

        public int getExpiryDate() {
            return this.expiryDate;
        }

        // returns true if financial transaction is successful
        // otherwise false
        public boolean charge(final int amount) {
            final int newBalance = this.balance - amount;
            if (newBalance < -this.limit) {
                return false;
            }
            this.balance = newBalance;
            return true;
        }

        // ------- PRIVATE METHODS ---------

        private int getCVV() {
            return this.CVV;
        }

        private int getBalance() {
            return this.balance;
        }

        private void setBalance(final int balance) {
            this.balance = balance;
        }

        private int getLimit() {
            return limit;
        }

        private void setLimit(final int limit) {
            this.limit = limit;
        }
    }
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X