2011-08-23 8 views
10

bien, sé que es la regla:¿Por qué la interfaz solo se puede declarar en la clase de nivel superior?

De acuerdo con JLS: 8.1.3 Clases Internas e instancias cercadas, interiores clases no puede declarar inicializadores estáticos o interfaces miembros. Las clases internas no pueden declarar miembros estáticos, a menos que sean campos constantes de tiempo de compilación.

8.5.2 De acuerdo con declaraciones de tipo estático miembros, "interfaces de miembros son siempre implícitamente estática. Está permitido pero no es necesario para la declaración de un miembro de interfaz de enumerar explícitamente la modificador static". Siempre son de alto nivel, no interiores.

Me pregunto por qué. ¿Qué puede pasar si se nos permite declarar la interfaz dentro de una clase interna? ¿No se convertirá la clase interna en una clase de nivel superior si la agrego a otro archivo de Clase?

Respuesta

7

¿La clase interior no se convertirá en clase de nivel superior si la coloco en otro archivo de clase?

No, todavía es una clase interna, que el nombre del archivo indica (IIRC es OuterClass$InnerClass.class).

Las clases internas tienen acceso a los atributos de la clase externa, es decir, dependen de la instancia de su clase externa. Con las interfaces no podrías hacer esto. Piense en una clase completamente no relacionada que tendría que ser creada por la instancia correspondiente de la clase externa. ¿Cómo se haría eso si la clase externa no sabe quién implementa esa interfaz?

Lo que puede hacer es declarar interfaces de electricidad estática en su clase externa, por lo que la mera utilización de la externa como un espacio de nombres:

public class OuterClass { 
    public static interface InnerInterface { //protected and private would be fine too, depending on what makes sense 
    } 
} 

Editar: en realidad, leí mal la pregunta y ya que las interfaces son estáticas de todos modos, esto es una actualizado fragmento de código:

public class OuterClass { 
    public static InnerClass { //static inner class making OuterClass just be a namespace 
    public interface InnerInnerInterface { //protected and private would be fine too, depending on what makes sense 
    } 
    } 
} 

Como solución alternativa se podría definir una clase interna interior abstracto, con el inconveniente de que hay que atenerse a la única restricción de la herencia.

+0

Hmm, ¡muy interesante! Nunca sé que la interfaz puede declararse como estática. ¿Qué significa "estático" aquí? He probado la interfaz estática de Google pero no he encontrado nada. P/s: solo edite mi publicación en la línea que cita, para corregir el error de gramática. –

+2

@ W.N .: Las interfaces son implícitamente estáticas. Esa declaración es solo redundante. –

+1

@Ryan buen punto, también acabo de volver a leer la pregunta y actualizaré mi respuesta. – Thomas

1

Se supone que las clases internas son detalles de implementación de la clase de nivel superior y, por lo tanto, deben ser invisibles para el cliente. Cualquier funcionalidad a la que desee acceder de una clase interna debe hacerlo a través de la clase de nivel superior, porque conceptualmente hablando, esa funcionalidad debe ser visible solo como funcionalidad de la clase de nivel superior, de modo que el diseñador de clase pueda intercambiar o de lo contrario cambiar drásticamente las clases internas sin romper las compilaciones de los clientes.

+2

Eso es todo una cuestión de opinión. Si las clases internas fueran solo para uso interno de la clase padre, no se te permitiría hacerlas 'públicas '. – skaffman

2

Por definición, una clase de nivel superior y su (s) clase (s) interna (s) están estrechamente acopladas. Las interfaces son un medio para reducir el acoplamiento.

+1

¿Incluso si solo necesito usar de forma privada esa interfaz para la clase interna? –

+0

No es necesariamente un buen argumento, ya que he escrito una serie de interfaces privadas, anidadas, que se usan solo dentro del alcance de una sola clase. –

4

Piénselo en términos de contexto estático frente a no estático. Una clase de "nivel superior" establece un contexto estático porque se puede acceder sin ninguna instancia adjunta. Es decir. puedes acceder a las clases de nivel superior desde un método principal. Lo mismo se aplica a cualquier miembro estático de una clase de nivel superior. Sin embargo, una clase interna no existe en * ni establece ningún contexto estático. Por lo tanto, no puede tener ningún miembro estático, y solo se puede acceder a través de una instancia de su clase contenedora, como constructores y otros miembros de la instancia. Desde un método principal, no sería capaz de decir Outer.Inner.SOME_FIELD porque los miembros de una clase interna solo tienen significado con respecto a la clase contenedora.

* tipo de

+0

Esta respuesta hará que la respuesta de Thomas sea más clara. +1. –

Cuestiones relacionadas