2010-06-14 32 views
6

Soy nuevo en Java (tienen experiencia con C#),¿Cómo puedo crear una nueva instancia de clase de una clase dentro de una clase (estática)?

esto es lo que quiero hacer:

public final class MyClass 
{ 
    public class MyRelatedClass 
    { 
     ... 
    } 
} 

public class OtherRandomClass 
{ 
    public void DoStuff() 
    { 
     MyRelatedClass data = new MyClass.MyRelatedClass(); 
    } 
} 

que da este error en Eclipse:

No enclosing instance of type BitmapEffects is accessible. Must qualify the allocation with an enclosing instance of type BitmapEffects (e.g. x.new A() where x is an instance of BitmapEffects).

Este es posible en C# con clases estáticas, ¿cómo debería hacerse aquí?

+0

Posible duplicado de [Java - No se puede acceder a ninguna instancia adjunta de tipo Foo] (http://stackoverflow.com/questions/9560600/java-no-enclosing-instance-of-type- foo-is-accessible) – fabian

Respuesta

2

Respondiendo a los comentarios sobre empaquetar múltiples clases en un archivo: a diferencia de .NET, la mayoría de las implementaciones de java imponen una estricta correlación entre el nombre del tipo de clase pública y el nombre del archivo en el que se declara el tipo de clase. no es un requisito difícil, pero no se usa un sistema donde la correlación no se aplica.El JLS - 7.6 Top Level Type Declarations dice esto:

When packages are stored in a file system (§7.2.1), the host system may choose to enforce the restriction that it is a compile-time error if a type is not found in a file under a name composed of the type name plus an extension (such as .java or .jav) if either of the following is true:

  • The type is referred to by code in other compilation units of the package in which the type is declared.
  • The type is declared public (and therefore is potentially accessible from code in other packages).

Ver esta cuestión de forma: multiple class declarations in one file

Si usted está buscando para crear un espacio de nombres para encerrar sus clases relacionadas, a continuación, utilizando las clases internas estáticas son lo que necesita. La declaración estática no significa una sola instalación, todavía se pueden crear instancias, el static significa que se pueden crear instancias sin necesidad de una referencia a la clase adjunta. Como la clase adjunta es solo para agrupar, y no datos, está seguro convirtiéndolo en estático. Para aclarar que la clase adjunta es solo para agrupar, debe declararla como interface, de modo que no pueda crearse una instancia y no tenga detalles de implementación.

Aunque personalmente, me abstendría de hacer esto: en Java, los paquetes se utilizan para imponer un espacio de nombres. El uso de clases internas para esto rápidamente se vuelve engorroso. (¡Lo he intentado!)

+0

ah gracias por la información :). (y gracias a todos por su ayuda) – Mervin

3

Intente definir MyRelatedClass como estático.

edición
Más sobre el tema
http://java.sun.com/docs/books/tutorial/java/javaOO/nested.html

+0

No quiero que MyRelatedClass sea estático, necesito varias instancias del mismo. – Mervin

+1

@Mervin por favor lea la descripción en el enlace (o la respuesta de Matt). Si la clase interna es "estática", no significa que solo hay una instancia de ella. Significa que MyRelatedClass no se asociará a ninguna instancia particular de MyClass y no podrá acceder a los miembros de su instancia (clase padre). –

+0

@Mervin - Eso no es lo que significa estático en este contexto. Efectivamente hace que se comporte como una clase de nivel superior a pesar de estar anidado en MyClass. – Robin

19

La forma en que usted ha definido MyRelatedClass, es necesario tener una instancia de MyClass para poder acceder/crear instancias de esta clase.

Normalmente, en Java utiliza este patrón cuando una instancia de MyRelatedClass necesita acceder a algunos campos de una instancia MyClass (de ahí las referencias a una "instancia adjunta" en la advertencia del compilador).

Algo como esto debería compilar:

public void doStuff() { 
    MyClass mc = new MyClass(); 
    MyRelatedClass data = mc.new MyRelatedClass(); 
} 

Sin embargo, si una instancia MyRelatedClass no necesita acceso a los campos de Es encerrando instancia (MyClass 's campos), entonces debería considerar la definición MyRelatedClass como una clase estática, esto permitirá que el código original que ha publicado compile.

La diferencia en tener una clase anidada (lo que has publicado) y una clase anidada estática (una static class dentro de un class) es que en el primer caso, la clase anidada pertenece a una instancia de la clase padre, mientras que el último no tiene tal relación, solo una relación lógica/espacio de nombres.

+4

Crear una clase interna (no estática) en algo que no sea un 'this' implícito me pone enfermo. –

+0

así que estoy tratando de lograr lo que puedo hacer en C#: //[MapManagement.cs] espacio de nombres MapManagement { clase estática pública MapManager { ... } clase pública SpecialMapFile { ... } } Quiero 2 clases (no estáticas) en 1 archivo, de alguna manera en Java esto no está permitido .. error: "el tipo público * nombre * necesita definirse en su propio archivo" así que esta fue mi solución para eso, quiero 1 paquete y quiero tener la clase relacionada agrupada en su propio archivo – Mervin

+0

@Mervin como has visto Java solo permite una clase pública de nivel superior por archivo. Las clases relacionadas solo se pueden definir en el mismo paquete, en archivos separados. –

0

Sí, las clases anidadas no estáticas tienen acceso a los miembros de la instancia de clases externas y, por lo tanto, se deben crear para una instancia de la clase externa. Así que hay dos opciones:

  1. hacer que la clase anidada estática como sugiere Mervin, o
  2. crearlo utilizando una instancia de la clase externa como sugiere el mensaje de error.

En la práctica, raramente creo una instancia de la clase interna, excepto en los métodos de la clase externa, y raramente hago tales clases mutables, pero esto soy solo yo.

+0

así que estoy tratando de lograr lo que puedo hacer en C#: //[MapManagement.cs] espacio de nombres MapManagement {public static class MapManager {...} public class SpecialMapFile {...}} Quiero 2 clases (no- estático) en 1 archivo, de alguna manera en Java esto no está permitido .. error: "el nombre de tipo público debe definirse en su propio archivo", así que esta fue mi solución a eso, quiero 1 paquete y quiero tener información relacionada clase agrupada en su propio archivo - – Mervin

Cuestiones relacionadas