Klasy zagnieżdżone / wewnętrzne, lokalne, anonimowe, wyrażenia Lambda

 

UWAGA! ZNAJOMOŚĆ TEGO MATERIAŁU NIE JEST OBOWIĄZKOWA.

 

Istnieje możliwość definiowania klas wewnątrz klasy.

Przykład:

class MyClass {
    ...
    class NestedClass {
        ...
    }
}

Klas zagnieżdżonych warto użyć, gdy:

  • chcemy logicznie zgrupować klasy, które są używane wyłącznie w jednym miejscu; jeśli klasa wewnętrzna jest użyteczna wyłącznie dla swojej klasy zewnętrznej, wówczas logicznym rozwiązaniem jest umieszenie jej wewnątrz klasy zewnętrznej, żeby definicje obu klas były ze sobą ściśle związane;
  • chcemy zwiększyć poziom hermetyzacji (encapsulation); załóżmy, że mamy klasę zewnętrzną, która musi być prywatna (private); stosując klasę wewnętrzną względem drugiej prywatnej klasy zewnętrznej możemy zapewnić dostęp klasy wewnętrznej do elementów klasy zewnętrznej mimo, że klasa zewnętrzna jest prywatna.

 

Nie można utworzyć instancji (obiektu) klasy zagnieżdżonej bez utworzenia obiektu klasy zewnętrznej.

 

Przykład użycia klasy zagnieżdżonej:

public class Outer {
    public int a = 1;

    class Inner {
        public int a = 2;

        void methodInInner( int a ) {
            System.out.println( "a = " + a );        // zostanie wyświetlona wartość 3
            System.out.println( "this.a = " + this.a );        // zostanie wyświetlona wartość 2
            System.out.println( "Outer.this.a = " + Outer.this.a );        // zostanie wyświetlona wartość 1
        }
    }

    public static void main( String[] args) {
        Outer outer = new Outer();    // Musisz utworzyć instancję/obiekt klasy Outer, aby użyć klasy Inner
        Outer.Inner inner = outer.new Inner();    // Dopiero teraz możesz skonstruować obiekt klasy Inner
        inner.methodInInner( 3 );
    }
}

Ponadto wśród rodzajów klas zagnieżdżonych rozróżniamy klasy wewnętrzne, klasy lokalne, klasy anonimowe - patrz: https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html

 

 

Klasy lokalne (ang. Local Classes)

Klasy lokalne są zazwyczaj zdefiniowane wewnątrz ciała metody.

https://docs.oracle.com/javase/tutorial/java/javaOO/localclasses.html

 

 

Klasy anonimowe (ang. Anonymous Classes)

https://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html

Klasy anonimowe to klasy lokalne które nie mają nazwy - stanowią bezpośrednią implementację interfejsu lub klasy - to raczej "wyrażenia" niż regularne klasy. Użycie klasy anonimowej pozwala na jednoczesne zadeklarowanie i wygenerowanie obiektu danej klasy. Klas anonimowych używamy, gdy obiektu danej klasy potrzebujemy tylko raz - gdy potrzebujemy tylko jednej instancji danej klasy.

 

 

Wyrażenia Lambda (ang. Lambda Expressions)

https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html

Wyrażenia Lambda to dodatkowe uproszczenie wyrażeń, jakimi są klasy anonimowe. Są one używane, gdy w klasie używana jest wyłącznie jedna metoda.