Java - clases internas
En este capítulo, discutiremos las clases internas de Java.
Clases anidadas
En Java, al igual que los métodos, las variables de una clase también pueden tener otra clase como miembro. Escribir una clase dentro de otra está permitido en Java. La clase escrita dentro se llamanested class, y la clase que contiene la clase interna se llama outer class.
Syntax
A continuación se muestra la sintaxis para escribir una clase anidada. Aqui la claseOuter_Demo es la clase externa y la clase Inner_Demo es la clase anidada.
class Outer_Demo {
class Inner_Demo {
}
}
Las clases anidadas se dividen en dos tipos:
Non-static nested classes - Estos son los miembros no estáticos de una clase.
Static nested classes - Estos son los miembros estáticos de una clase.
Clases internas (clases anidadas no estáticas)
Las clases internas son un mecanismo de seguridad en Java. Sabemos que una clase no se puede asociar con el modificador de acceso.private, pero si tenemos la clase como miembro de otra clase, entonces la clase interna puede hacerse privada. Y esto también se usa para acceder a los miembros privados de una clase.
Las clases internas son de tres tipos dependiendo de cómo y dónde las defina. Ellos son -
- Clase interior
- Clase interna de método local
- Clase interna anónima
Clase interior
Crear una clase interna es bastante simple. Solo necesitas escribir una clase dentro de una clase. A diferencia de una clase, una clase interna puede ser privada y una vez que declaras privada una clase interna, no se puede acceder a ella desde un objeto fuera de la clase.
A continuación se muestra el programa para crear una clase interna y acceder a ella. En el ejemplo dado, hacemos que la clase interna sea privada y accedemos a la clase a través de un método.
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();
}
}
Aquí puedes observar que Outer_Demo es la clase externa, Inner_Demo es la clase interior, display_Inner() es el método dentro del cual estamos instanciando la clase interna, y este método se invoca desde el main método.
Si compila y ejecuta el programa anterior, obtendrá el siguiente resultado:
Output
This is an inner class.
Accediendo a los miembros privados
Como se mencionó anteriormente, las clases internas también se utilizan para acceder a los miembros privados de una clase. Supongamos que una clase tiene miembros privados para acceder a ellos. Escriba una clase interna en ella, devuelva los miembros privados de un método dentro de la clase interna, digamos,getValue(), y finalmente desde otra clase (desde la que desea acceder a los miembros privados) llame al método getValue () de la clase interna.
Para crear una instancia de la clase interna, inicialmente debe crear una instancia de la clase externa. A partir de entonces, utilizando el objeto de la clase externa, la siguiente es la forma en que puede crear una instancia de la clase interna.
Outer_Demo outer = new Outer_Demo();
Outer_Demo.Inner_Demo inner = outer.new Inner_Demo();
El siguiente programa muestra cómo acceder a los miembros privados de una clase usando la clase interna.
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());
}
}
Si compila y ejecuta el programa anterior, obtendrá el siguiente resultado:
Output
This is the getnum method of the inner class: 175
Clase interna de método local
En Java, podemos escribir una clase dentro de un método y este será un tipo local. Al igual que las variables locales, el alcance de la clase interna está restringido dentro del método.
Una clase interna local de método se puede instanciar solo dentro del método donde se define la clase interna. El siguiente programa muestra cómo utilizar una clase interna local de método.
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();
}
}
Si compila y ejecuta el programa anterior, obtendrá el siguiente resultado:
Output
This is method inner class 23
Clase interna anónima
Una clase interna declarada sin un nombre de clase se conoce como anonymous inner class. En el caso de clases internas anónimas, las declaramos y las instanciamos al mismo tiempo. Generalmente, se utilizan siempre que necesite anular el método de una clase o interfaz. La sintaxis de una clase interna anónima es la siguiente:
Syntax
AnonymousInner an_inner = new AnonymousInner() {
public void my_method() {
........
........
}
};
El siguiente programa muestra cómo anular el método de una clase usando una clase interna anónima.
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();
}
}
Si compila y ejecuta el programa anterior, obtendrá el siguiente resultado:
Output
This is an example of anonymous inner class
De la misma manera, puede anular los métodos de la clase concreta, así como la interfaz, utilizando una clase interna anónima.
Clase interna anónima como argumento
Generalmente, si un método acepta un objeto de una interfaz, una clase abstracta o una clase concreta, entonces podemos implementar la interfaz, extender la clase abstracta y pasar el objeto al método. Si es una clase, podemos pasarla directamente al método.
Pero en los tres casos, puede pasar una clase interna anónima al método. Aquí está la sintaxis de pasar una clase interna anónima como argumento de método:
obj.my_Method(new My_Class() {
public void Do() {
.....
.....
}
});
El siguiente programa muestra cómo pasar una clase interna anónima como argumento de método.
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";
}
});
}
}
Si compila y ejecuta el programa anterior, le da el siguiente resultado:
Output
Hello, This is an example of anonymous inner class as an argument
Clase anidada estática
Una clase interna estática es una clase anidada que es un miembro estático de la clase externa. Se puede acceder sin instanciar la clase externa, utilizando otros miembros estáticos. Al igual que los miembros estáticos, una clase anidada estática no tiene acceso a las variables de instancia ni a los métodos de la clase externa. La sintaxis de la clase anidada estática es la siguiente:
Syntax
class MyOuter {
static class Nested_Demo {
}
}
Crear una instancia de una clase anidada estática es un poco diferente de crear una instancia de una clase interna. El siguiente programa muestra cómo utilizar una clase anidada estática.
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();
}
}
Si compila y ejecuta el programa anterior, obtendrá el siguiente resultado:
Output
This is my nested class