2011-06-02 16 views
31

tengo una clase MyClass y una clase interna MyNestedClass así:clase anidada/interior en archivo externo

public class MyClass { 
    ... 
    public class MyNestedClass { 
    ... 
    } 
} 

Ambas clases son muy largas. Por eso me gustaría separarlos en dos archivos diferentes, sin romper la jerarquía. Esto se debe a que la clase anidada no debe ser visible para el programador que usa MyClass.

¿Hay alguna manera de lograr eso?

+0

homóloga pregunta http: // stackoverflow.com/questions/2764234/partial-classes-partial-class-file – Terrance

+0

Tuve un problema similar y lo resolví aquí: http://stackoverflow.com/q/27284667/1190665 Al menos eso es lo mejor que se me ocurrió. – John

Respuesta

20

Puede hacer que el paquete de clase interna sea privado, lo que significa que solo será accesible desde otras clases en exactamente el mismo paquete. Esto también se hace con bastante frecuencia para las clases ocultas dentro de los paquetes estándar JDK como java.lang o java.util.

en PKG/MyClass.java

public class MyClass { 
    ... 
} 

en PKG/MyHiddenClass.java

class MyHiddenClass { 

    final MyClass outer; 

    MyHiddenClass(MyClass outer) 
    { 
     this.outer = outer; 
    } 
    ... 
} 

Ahora cuando se desea acceder a los métodos o variables de la clase externa que necesita usar el prefijo con outer. pero obtienes esencialmente la misma funcionalidad que antes cuando la referencia a la instancia externa fue creada sintéticamente por el compilador.

+0

Gracias, lo hizo de esa manera. – Alp

+7

Eso técnicamente no es todavía una clase interna, sin embargo. – AJMansfield

+5

los atributos privados de 'MyClass' no serán evaluables desde' MyHiddenClass', y 'MyHiddenClass' está protegido, no es privado. – SparK

6

No. Los códigos fuente de Java no se pueden dividir en varios archivos. Necesitarías una construcción similar a una clase parcial como en C#, que Java no tiene.

+0

¿Existe tal vez otra alternativa para ocultar una clase al programador? – Alp

+0

Claro, vea las respuestas a continuación. – retrodrone

4

Objetos de inner Las clases mantienen referencias implícitas a los objetos de la clase paren. Si la clase anidada no es static (es interior) no puede. Pero si la clase anidada no necesita acceder directamente a las instancias de clase del padre y no necesita acceder a los campos privados, debe estar bien para refactorizar, mover la clase interna y hacer no declararlo público (fuera de ese paquete) no se puede acceder).

+0

Gracias por la explicación – Alp

1

Puede crear clases base abstractas que amplíe en ambas.

Sin embargo, si esas clases son grandes, sería mejor que reevalúe el diseño de su clase y vea si puede refactorizar en clases que representan una preocupación cada una.

2

Sí, usando cascada puente. Un puente de cascada es una clase interna abstracta y no estática que se define en cualquier otro lugar.

MyClass.java

public class MyClass { 
    public abstract class CascadeJumper {} 
} 

MyNestedClass.java

public class MyNestedClass extends MyClass.CascadeJumper { 
    MyNestedClass(MyClass dollarOne) { 
    dollarOne.super(); // yes, is possible! 
    } 
} 

Saludos

+0

No veo cómo podría funcionar esto. De 'MyNestedClass', solo podrá acceder a los métodos y campos públicos de' MyClass', como cualquier otra clase. – Alphaaa

+0

@Alphaaa No, puedes acceder a campos privados, enums privados, clases privadas y métodos privados, constructores privados, ¡simplemente todo de 'MyClass' en' MyNestedClass'! ¡Intentalo! –

+0

Lo hice y no puedes. De hecho, incluso las clases internas normales no pueden según esto: http://docstore.mik.ua/orelly/java-ent/jnut/ch03_13.htm. El compilador de java en realidad convierte los accesos a los campos privados de la clase externa generando métodos privados de paquete y sustituye cualquier acceso de campo directo con una llamada a uno de estos métodos generados. Todas las clases son en efecto de nivel superior. – user2219808

Cuestiones relacionadas