Java - klasy wewnętrzne
W tym rozdziale omówimy wewnętrzne klasy Javy.
Klasy zagnieżdżone
W Javie, podobnie jak w metodach, zmienne klasy mogą mieć inną klasę jako jej składową. Pisanie klasy w innej klasie jest dozwolone w Javie. Klasa zapisana w programie nazywa sięnested class, a klasa, która zawiera klasę wewnętrzną, nazywa się outer class.
Syntax
Poniżej znajduje się składnia do napisania klasy zagnieżdżonej. Tutaj klasaOuter_Demo jest klasą zewnętrzną i klasą Inner_Demo to klasa zagnieżdżona.
class Outer_Demo {
class Inner_Demo {
}
}
Zagnieżdżone klasy są podzielone na dwa typy -
Non-static nested classes - To są niestatyczni członkowie klasy.
Static nested classes - To są statyczni członkowie klasy.
Klasy wewnętrzne (niestatyczne klasy zagnieżdżone)
Klasy wewnętrzne są mechanizmem bezpieczeństwa w Javie. Wiemy, że klasa nie może być powiązana z modyfikatorem dostępuprivate, ale jeśli mamy klasę jako członka innej klasy, wówczas klasa wewnętrzna może zostać ustawiona jako prywatna. Służy również do uzyskiwania dostępu do prywatnych członków klasy.
Klasy wewnętrzne dzielą się na trzy typy w zależności od tego, jak i gdzie je zdefiniujesz. Oni są -
- Klasa wewnętrzna
- Metoda - lokalna klasa wewnętrzna
- Anonimowa klasa wewnętrzna
Klasa wewnętrzna
Tworzenie klasy wewnętrznej jest dość proste. Wystarczy napisać klasę w ramach klasy. W przeciwieństwie do klasy, klasa wewnętrzna może być prywatna i po zadeklarowaniu klasy wewnętrznej jako prywatnej nie można uzyskać do niej dostępu z obiektu spoza klasy.
Poniżej znajduje się program do tworzenia klasy wewnętrznej i uzyskiwania do niej dostępu. W podanym przykładzie ustawiamy klasę wewnętrzną jako prywatną i uzyskujemy do niej dostęp za pomocą metody.
Example
class Outer_Demo {
int num;
// inner class
private class Inner_Demo {
public void print() {
System.out.println("This is an inner class");
}
}
// Accessing he inner class from the method within
void display_Inner() {
Inner_Demo inner = new Inner_Demo();
inner.print();
}
}
public class My_class {
public static void main(String args[]) {
// Instantiating the outer class
Outer_Demo outer = new Outer_Demo();
// Accessing the display_Inner() method.
outer.display_Inner();
}
}
Tutaj możesz to zaobserwować Outer_Demo jest klasą zewnętrzną, Inner_Demo jest klasą wewnętrzną, display_Inner() jest metodą, w której tworzymy instancję klasy wewnętrznej, a ta metoda jest wywoływana z main metoda.
Jeśli skompilujesz i uruchomisz powyższy program, otrzymasz następujący wynik -
Output
This is an inner class.
Dostęp do członków prywatnych
Jak wspomniano wcześniej, klasy wewnętrzne są również używane do uzyskiwania dostępu do prywatnych członków klasy. Załóżmy, że klasa ma prywatnych członków, którzy mają do nich dostęp. Napisz w nim klasę wewnętrzną, zwróć prywatne elementy członkowskie z metody w klasie wewnętrznej, powiedzmy,getValue(), a na koniec z innej klasy (z której chcesz uzyskać dostęp do prywatnych członków) wywołaj metodę getValue () klasy wewnętrznej.
Aby utworzyć instancję klasy wewnętrznej, początkowo musisz utworzyć instancję klasy zewnętrznej. Następnie, używając obiektu klasy zewnętrznej, następujący jest sposób, w jaki można utworzyć instancję klasy wewnętrznej.
Outer_Demo outer = new Outer_Demo();
Outer_Demo.Inner_Demo inner = outer.new Inner_Demo();
Poniższy program pokazuje, jak uzyskać dostęp do prywatnych członków klasy przy użyciu klasy wewnętrznej.
Example
class Outer_Demo {
// private variable of the outer class
private int num = 175;
// inner class
public class Inner_Demo {
public int getNum() {
System.out.println("This is the getnum method of the inner class");
return num;
}
}
}
public class My_class2 {
public static void main(String args[]) {
// Instantiating the outer class
Outer_Demo outer = new Outer_Demo();
// Instantiating the inner class
Outer_Demo.Inner_Demo inner = outer.new Inner_Demo();
System.out.println(inner.getNum());
}
}
Jeśli skompilujesz i uruchomisz powyższy program, otrzymasz następujący wynik -
Output
This is the getnum method of the inner class: 175
Metoda - lokalna klasa wewnętrzna
W Javie możemy napisać klasę w ramach metody i będzie to typ lokalny. Podobnie jak zmienne lokalne, zakres klasy wewnętrznej jest ograniczony w ramach metody.
Wystąpienie lokalnej klasy wewnętrznej metody można utworzyć tylko w ramach metody, w której zdefiniowano klasę wewnętrzną. Poniższy program pokazuje, jak używać lokalnej klasy wewnętrznej metody.
Example
public class Outerclass {
// instance method of the outer class
void my_Method() {
int num = 23;
// method-local inner class
class MethodInner_Demo {
public void print() {
System.out.println("This is method inner class "+num);
}
} // end of inner class
// Accessing the inner class
MethodInner_Demo inner = new MethodInner_Demo();
inner.print();
}
public static void main(String args[]) {
Outerclass outer = new Outerclass();
outer.my_Method();
}
}
Jeśli skompilujesz i uruchomisz powyższy program, otrzymasz następujący wynik -
Output
This is method inner class 23
Anonimowa klasa wewnętrzna
Klasa wewnętrzna zadeklarowana bez nazwy klasy jest znana jako anonymous inner class. W przypadku anonimowych klas wewnętrznych deklarujemy je i tworzymy w tym samym czasie. Zwykle są używane, gdy zachodzi potrzeba zastąpienia metody klasy lub interfejsu. Składnia anonimowej klasy wewnętrznej jest następująca -
Syntax
AnonymousInner an_inner = new AnonymousInner() {
public void my_method() {
........
........
}
};
Poniższy program pokazuje, jak przesłonić metodę klasy przy użyciu anonimowej klasy wewnętrznej.
Example
abstract class AnonymousInner {
public abstract void mymethod();
}
public class Outer_class {
public static void main(String args[]) {
AnonymousInner inner = new AnonymousInner() {
public void mymethod() {
System.out.println("This is an example of anonymous inner class");
}
};
inner.mymethod();
}
}
Jeśli skompilujesz i uruchomisz powyższy program, otrzymasz następujący wynik -
Output
This is an example of anonymous inner class
W ten sam sposób można przesłonić metody konkretnej klasy, a także interfejs, używając anonimowej klasy wewnętrznej.
Anonimowa klasa wewnętrzna jako argument
Generalnie, jeśli metoda akceptuje obiekt interfejsu, klasę abstrakcyjną lub klasę konkretną, możemy zaimplementować interfejs, rozszerzyć klasę abstrakcyjną i przekazać obiekt do metody. Jeśli jest to klasa, możemy ją bezpośrednio przekazać do metody.
Ale we wszystkich trzech przypadkach można przekazać do metody anonimową klasę wewnętrzną. Oto składnia przekazywania anonimowej klasy wewnętrznej jako argumentu metody -
obj.my_Method(new My_Class() {
public void Do() {
.....
.....
}
});
Poniższy program pokazuje, jak przekazać anonimową klasę wewnętrzną jako argument metody.
Example
// interface
interface Message {
String greet();
}
public class My_class {
// method which accepts the object of interface Message
public void displayMessage(Message m) {
System.out.println(m.greet() +
", This is an example of anonymous inner class as an argument");
}
public static void main(String args[]) {
// Instantiating the class
My_class obj = new My_class();
// Passing an anonymous inner class as an argument
obj.displayMessage(new Message() {
public String greet() {
return "Hello";
}
});
}
}
Jeśli skompilujesz i uruchomisz powyższy program, otrzymasz następujący wynik -
Output
Hello, This is an example of anonymous inner class as an argument
Statyczna klasa zagnieżdżona
Statyczna klasa wewnętrzna jest klasą zagnieżdżoną, która jest statycznym składnikiem klasy zewnętrznej. Można uzyskać do niego dostęp bez tworzenia wystąpienia klasy zewnętrznej, używając innych statycznych elementów członkowskich. Podobnie jak statyczne elementy członkowskie, statyczna klasa zagnieżdżona nie ma dostępu do zmiennych instancji i metod klasy zewnętrznej. Składnia statycznej klasy zagnieżdżonej jest następująca -
Syntax
class MyOuter {
static class Nested_Demo {
}
}
Tworzenie wystąpienia statycznej klasy zagnieżdżonej różni się nieco od tworzenia wystąpienia klasy wewnętrznej. Poniższy program pokazuje, jak używać statycznej klasy zagnieżdżonej.
Example
public class Outer {
static class Nested_Demo {
public void my_method() {
System.out.println("This is my nested class");
}
}
public static void main(String args[]) {
Outer.Nested_Demo nested = new Outer.Nested_Demo();
nested.my_method();
}
}
Jeśli skompilujesz i uruchomisz powyższy program, otrzymasz następujący wynik -
Output
This is my nested class