inner - java classes
¿Cuáles son los propósitos de las clases internas? (8)
Estoy revisando el concepto de clases internas en Java. tan lejos de lo que he entendido y aplicado las clases internas de Java tiene un enlace o acceso a los métodos y campos de su clase externa / adjunta.
Mi pregunta:
- ¿Cuándo debería crear o definir una clase interna?
- ¿Las clases internas se consideran llamadas "clases de ayuda"?
- ¿Cuáles son los indicadores para que hagas una clase interna y cuál es su otro propósito?
Ver el javadoc por las razones principales.
Si por "clase auxiliar" te refieres a algo solo para uso interno, entonces no, no necesariamente. Es posible que desee hacer algo como
class Outer { private static class Inner implements InterestingInterface { // whatever } public InterestingInterface make_something_interesting() { return new Inner(); } }
Aquí,
Inner
no es una "clase de ayuda" en el sentido de que el mundo exterior sí puede ver instancias de ella, pero su implementación está completamente oculta: el mundo exterior solo sabe que obtiene algún objeto que implementaInterestingInterface
.
Como regla general, los objetos deben diseñarse para una sola responsabilidad (altamente cohesivo ). En otras palabras, cualquier objeto diseñado bien debe realizar una única tarea coherente . Esto se consideraría la mejor práctica para el diseño orientado a objetos.
A veces, sin embargo, un desarrollador puede diseñar una clase que requiera una clase especializada separada para funcionar. Esta clase especializada separada podría considerarse una clase auxiliar .
Si la clase auxiliar no es utilizada por ninguna otra clase , entonces se consideraría un candidato principal como una clase interna
Tal como lo señaló ncmathsadist anteriormente, un ejemplo de uso de clase interna estaría en la implementación de controladores de eventos .
Por ejemplo, al diseñar una interfaz gráfica de usuario (GUI), un desarrollador puede haber creado un botón que realiza una tarea en particular después de que el usuario la presiona.
El botón necesitaría un controlador de eventos que escuche cuando se presione ese botón en particular.
En este caso, la mejor práctica sería crear el controlador de eventos para el botón como una clase interna, ya que la clase interna no se utilizaría en ningún otro lugar que no sea con el botón específico dentro de la clase de la GUI.
Esta es una pregunta de estilo. Todo lo que se puede hacer con una clase interna también se puede hacer como una serie de clases externas. Las clases internas son especialmente útiles para las clases que son livianas o están estrechamente ligadas a la clase que las incluye. Por ejemplo, un comparador es frecuentemente ambas cosas. Necesita un conocimiento profundo de la implementación de la clase, y solo puede tener unas pocas líneas. Puede ser un candidato ideal como una clase interna.
Las clases internas son las mejores para agrupar lógicamente las clases que se usan en un solo lugar. Por ejemplo, si desea crear una clase que sea utilizada SOLAMENTE para encerrar una clase, entonces no tiene sentido crear un archivo separado para eso. En cambio, puede agregarlo como "clase interna"
Según javadoc :
Las razones convincentes para usar clases anidadas incluyen lo siguiente:
- Es una forma de agrupar lógicamente clases que solo se usan en un solo lugar.
- Aumenta la encapsulación.
- Puede conducir a un código más legible y mantenible.
Si encuentra que hay suficiente código que podría mejorarse por clase, la clase nos proporciona especificar las estadísticas y el comportamiento con los campos y métodos, y no desea que esta clase se use fuera de la clase adjunta. deberías usar clase interna.
Aquí la clase interna está oculta del mundo exterior. La clase interna puede acceder al miembro privado de la clase adjunta que nos proporciona encapsulación.
Déjame dar un ejemplo ... Supongamos que quieres configurar el engranaje para que funcione y tienes una regla de negocios como que solo hay hasta 6 marchas. Para que pueda crear un Ciclo interno de la clase que tendría un método para configurar el engranaje. Ese método tiene alguna validación que se verifica antes de establecer el engranaje. Al igual que el ciclo se está ejecutando ... el número de engranaje es inferior a 6 ...
El mejor ejemplo es el código de manejo de eventos que usa clases internas (a veces clases internas anónimas) para crear eventos y oyentes sin crear objetos de evento por separado y clases de escucha de eventos para su evento.
Simplemente consideraría que esto es solo una característica del lenguaje. No recomendaría su uso si adoptamos OOD y obedecemos el principio SOLID.
Un propósito de las clases internas es unir oyentes. Por ejemplo, supongamos que tiene un JMenuItem
. Puede hacer que salga de su aplicación como se muestra en este código:
JMenuItem quitItem = new JMenuItem("Quit");
quitItem.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
//cleanup code before exiting
System.exit(0);
}
});
También es posible que desee que una clase tenga acceso a las variables de estado de la clase externa que es totalmente subordinada a esa clase. Por ejemplo, considere escribir una calculadora de color simple. Puede tener un área de texto en la que escriba un código hexadecimal. Cuando presionas enter, quieres que un JPanel muestre el color. Aquí hay un resumen de lo que podrías hacer.
public class ColorCalc extends JPanel implements Runnable
{
Color displayedColor;
JTextArea colorEnterArea;
public ColorCalc()
{
displayedColor = Color.white
colorEnterArea = new JTextArea();
}
public void run()
{
//build GUI here
}
public static void main(String[] args)
{
ColorCalc cc = new ColorCalc();
javax.swing.SwingUtilities.invokeLater(cc);
}
//subservient inner class with access to outer class state variable.
class ColorPanel extends JPanel
{
public void paintComponent(Graphics g)
{
g.setColor(displayedColor);
g.fillRect(0,0,getWidth(), getHeight());
}
}
}
Un uso clásico para una clase interna es la implementación de un iterador dentro de un contenedor ( ArrayList , por ejemplo, busque class Itr
). Todo lo que el contenedor quiere exponer al resto del mundo es un Iterator
. Sin embargo, tiene que crear alguna implementación concreta de ese iterador, posiblemente familiarizado con las partes internas del contenedor. El uso de una clase interna oculta la implementación, manteniéndola cerca de la implementación del contenedor. Y al ser interno (es decir, no estático), está vinculado a una instancia específica de ese contenedor, lo que le permite acceder a los miembros del contenedor privado.
Hay algunos tipos de clases internas : clase anidada no estática, clases locales y clases anónimas. Cada uno tiene un propósito algo diferente, así que cuando preguntes sobre una clase interna, debes especificar de qué tipo estás hablando.
Suponiendo que se refiera a clases internas no estáticas, diría que la razón para usarlas es lo mismo que usar clases regulares (es decir, abstracción y división del código en unidades lógicas), pero no hay razón para hacer que este uso de clases sea visible al resto del mundo. También puede hacer que las clases anidadas sean públicas, por supuesto, en cuyo caso las haría anidadas en lugar de independientes para expresar su estrecha relación con la clase externa.