J'essaie de faire un jeu de Tetris et j'obtiens l'erreur du compilateur
Shape is not an enclosing class
quand j'essaie de créer un objet
public class Test {
public static void main(String[] args) {
Shape s = new Shapes.ZShape();
}
}
J'utilise des classes internes pour chaque forme. Voici une partie de mon code
public class Shapes {
class AShape {
}
class ZShape {
}
}
Qu'est-ce que je fais mal ?
ZShape
n'est pas statique et nécessite donc une instance de la classe externe.
La solution la plus simple consiste à créer ZShape et toute classe imbriquée static
si vous le pouvez.
Je voudrais également faire tous les champs final
ou static final
que vous pouvez aussi bien.
Supposons que RetailerProfileModel soit votre classe principale et que RetailerPaymentModel en soit une classe interne. Vous pouvez créer un objet de la classe Inner en dehors de la classe comme suit:
RetailerProfileModel.RetailerPaymentModel paymentModel = new RetailerProfileModel().new RetailerPaymentModel();
Ce que je suggérerais n'est pas de convertir la classe non statique en une classe statique, car dans ce cas, votre classe interne ne peut pas accéder aux membres non statiques de la classe externe.
Exemple :
class Outer
{
class Inner
{
//...
}
}
Donc, dans ce cas, vous pouvez faire quelque chose comme:
Outer o = new Outer();
Outer.Inner obj = o.new Inner();
Comme indiqué dans le docs :
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
Parfois, nous devons créer une nouvelle instance d’une classe interne qui ne peut pas être statique car elle dépend de certaines variables globales de la classe parente. Dans cette situation, si vous essayez de créer l'instance d'une classe interne qui n'est pas statique, une erreur not an enclosing class
est générée.
En prenant l'exemple de la question, que se passe-t-il si ZShape
ne peut pas être statique car il nécessite une variable globale de Shape
classe?
Comment créer une nouvelle instance de ZShape
? C'est ainsi:
Ajouter un getter dans la classe parente:
public ZShape getNewZShape() {
return new ZShape();
}
Accédez-y comme ceci:
Shape ss = new Shape();
ZShape s = ss.getNewZShape();
Shape shape = new Shape();
Shape.ZShape zshape = shape.new ZShape();
Pas besoin de rendre la classe imbriquée statique, mais elle doit être publique
public class Test {
public static void main(String[] args) {
Shape shape = new Shape();
Shape s = shape.new Shape.ZShape();
}
}
J'ai rencontré le même problème. J'ai résolu en créant une instance pour chaque classe publique interne. en ce qui concerne votre situation, je vous suggère d’utiliser un héritage autre que les classes internes.
public class Shape {
private String shape;
public ZShape zShpae;
public SShape sShape;
public Shape(){
int[][] coords = noShapeCoords;
shape = "NoShape";
zShape = new ZShape();
sShape = new SShape();
}
class ZShape{
int[][] coords = zShapeCoords;
String shape = "ZShape";
}
class SShape{
int[][] coords = sShapeCoords;
String shape = "SShape";
}
//etc
}
alors vous pouvez new Shape (); et visitez ZShape à travers shape.zShape;
Dans le cas où la classe Parent est singleton, utilisez la méthode suivante:
Parent.Child childObject = (Parent.getInstance()).new Child();
où getInstance()
retournera l'objet singleton de la classe parent.
Une chose que je ne savais pas au début en lisant la réponse acceptée était que rendre une classe interne statique était fondamentalement la même chose que de la déplacer dans sa propre classe séparée.
Ainsi, en obtenant l'erreur
xxx n'est pas une classe englobante
Vous pouvez le résoudre de l’une des manières suivantes:
static
à la classe interne, ouPour répondre aux exigences de la question, nous pouvons mettre des classes en interface:
public interface Shapes {
class AShape{
}
class ZShape{
}
}
et ensuite utiliser comme auteur essayé avant:
public class Test {
public static void main(String[] args) {
Shape s = new Shapes.ZShape();
}
}
Si nous cherchons la solution "logique" appropriée, nous devrions utiliser fabric
modèle de conception