Clase interne

Clasele interne (eng: nested classes) sunt clase definite in interiorul altor clase conform exemplului de mai jos:

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

Pot fi definite urmatoarele tipuri de clase interne:

  • statice
  • de instanta (ne-statice)
  • locale
  • anonime

Clase interne statice

Clasele interne statice sunt declarate astfel:

class Outer {
    static class Nested {      
    }
}

Pentru a creea o instanta de clasa statica se utilizeaza sintaxa:

Outer.Nested instance = new Outer.Nested();

O clasa interna statica poate accesa doar variabilele statice din clasa externa. Variabilele de instance pot fi accesate doar printr-o referinta a clasei externe.

Clase interne de instanta

Clasele interne de instanta sunt definite astfel:

public class Outer {
 
    private String text = "I am private!";
 
    public class Inner {
 
        public void printText() {
            System.out.println(text);
        }
    }
}

Pentru a creea o instanta de clasa interna se utilizeaza sintaxa:

Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
inner.printText();

Clasele interne de instanta pot accesa mebrii claselor externe chair daca acestia sunt declarati private dupa cum se vede in exemplul de mai sus.

Daca o clasa interna declara un membru cu acelasi nume ca si clasa externa atunci membrul din clasa interna va ascunde membrul din clasa externa - clasa interna va vedea membrul declarat local nu cel din clasa externa. CU toate acestea java face posibila accesarea mebrului ascus din clasa externa utiilzand o sintaxa de genul: NumeClasaExterna.this.fieldName conform exemplului de mai jos:

public class Outer {
 
    private String text = "I am Outer private!";
 
    public class Inner {
 
        private String text = "I am Inner private";
 
        public void printText() {
            System.out.println(text);
            System.out.println(Outer.this.text);
        }
    }
}

Clase locale

O clasa locala este o clasa interna de instanta (ne statica) care este definita in interiorul unei metode sau a unui bloc {…}. O clasa locala poate fi definita astfel:

class Outer {
 
    public void printText() {
 
        class Local {
 
        }
 
        Local local = new Local();
    }
 
}

Clasele locale pot fi accesate doar din interiorul blocului unde au fost declarate. Clasele locale pot accesa variabilele membru locale si variabilele din cadrul clasei externe in acelasi mod ca si clasele interne de instanta. Clasele locale nu pot fi declarate statice dar pot fi declarate in cadrul unor blocuri statice.

Clase interne anonime

Clasele interne anonime sunt clase interne dar care nu au un nume. In mod uzual aceste tipuri de clase sunt definite ca si subclase ale unei clase sau ca si implementari ale unor interfete. Exmeplu de clasa anonima:

class SuperClass {
 
    public void doIt() {
        System.out.println("SuperClass doIt()");
    }
 
}
 
public class AnonymousTest {
 
    public static void main(String[] args) {
        SuperClass instance = new SuperClass() {
 
            public void doIt() {
                System.out.println("Anonymous class doIt()");
            }
        };
        instance.doIt();
    }
 
}

In urma rularii codul de mai sus va afisa:

Anonymous class doIt()

In mod similar o clasa anonima poate implementa o interfata conform exemplului de mai jos:

public interface MyInterface {
 
  public void doIt();
 
}
MyInterface instance = new MyInterface() {
 
    public void doIt() {
        System.out.println("Anonymous class doIt()");
    }
};
 
instance.doIt();

O clasa interna anonima poate declara variabile membru sau metode dar nu poate declara constructori.

Utilitatea claselor interne

Clasele interne pot fi utilizate pentru gruparea unui set de clase obtinand o relatie foarte stransa de interdependenta intre ele.

Un set complet de recomandari cu privire la situatiile cand pot fi utilizate clasele interne poate fi gasit pe pagina tutorialelor oficiale java aici.