I'm trying to make a Tetris game and I'm getting the compiler error
Shape is not an enclosing class
when I try to create an object
public class Test {
public static void main(String[] args) {
Shape s = new Shapes.ZShape();
}
}
I'm using inner classes for each shape. Here's part of my code
public class Shapes {
class AShape {
}
class ZShape {
}
}
What am I doing wrong ?
new Shape().new ZShape();
. The class ZShape
needs an enclosing instance to be instantiated.
AShape
and ZShape
extend the base class Shapes
. Nesting classes is not a really good design for this problem.
ZShape
is not static so it requires an instance of the outer class.
The simplest solution is to make ZShape and any nested class static
if you can.
I would also make any fields final
or static final
that you can as well.
Suppose RetailerProfileModel is your Main class and RetailerPaymentModel is an inner class within it. You can create an object of the Inner class outside the class as follows:
RetailerProfileModel.RetailerPaymentModel paymentModel
= new RetailerProfileModel().new RetailerPaymentModel();
What I would suggest is not converting the non-static class to a static class because in that case, your inner class can't access the non-static members of outer class.
Example :
class Outer
{
class Inner
{
//...
}
}
So, in such case, you can do something like:
Outer o = new Outer();
Outer.Inner obj = o.new Inner();
Outer.Inner obj = new Outer().new Inner();
()
is compulsory. However, C, C++ it's not a must. Here is an example which doesn't work. Moreover, I found this post. which is explaining more about grammar in Java and how they are parsed. I would love to see a sample case when this syntax is working for you.
As stated in the docs:
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
Sometimes, we need to create a new instance of an inner class that can't be static because it depends on some global variables of the parent class. In that situation, if you try to create the instance of an inner class that is not static, a not an enclosing class
error is thrown.
Taking the example of the question, what if ZShape
can't be static because it need global variable of Shape
class?
How can you create new instance of ZShape
? This is how:
Add a getter in the parent class:
public ZShape getNewZShape() {
return new ZShape();
}
Access it like this:
Shape ss = new Shape();
ZShape s = ss.getNewZShape();
Shape shape = new Shape();
Shape.ZShape zshape = shape.new ZShape();
In case if Parent class is singleton use following way:
Parent.Child childObject = (Parent.getInstance()).new Child();
where getInstance()
will return parent class singleton object.
I have encountered the same problem. I solved by creating an instance for every inner public Class. as for you situation, i suggest you use inheritance other than inner classes.
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
}
then you can new Shape(); and visit ZShape through shape.zShape;
No need to make the nested class as static but it must be public
public class Test {
public static void main(String[] args) {
Shape shape = new Shape();
Shape s = shape.new Shape.ZShape();
}
}
One thing I didn't realize at first when reading the accepted answer was that making an inner class static is basically the same thing as moving it to its own separate class.
Thus, when getting the error
xxx is not an enclosing class
You can solve it in either of the following ways:
Add the static keyword to the inner class, or
Move it out to its own separate class.
To achieve the requirement from the question, we can put classes into interface:
public interface Shapes {
class AShape{
}
class ZShape{
}
}
and then use as author tried before:
public class Test {
public static void main(String[] args) {
Shape s = new Shapes.ZShape();
}
}
If we looking for the proper "logical" solution, should be used fabric
design pattern
In case that someone has this issue trying to instance a third party component.
In my case was doing a unit test using this component: ChannelSftp.LsEntry
https://i.stack.imgur.com/1IajI.png
The workaround was:
ChannelSftp channelSftp = new ChannelSftp();
Constructor<ChannelSftp.LsEntry> constructor = (Constructor<ChannelSftp.LsEntry>) ChannelSftp.LsEntry.class.getDeclaredConstructors()[0];
constructor.setAccessible(true);
ChannelSftp.LsEntry lsEntry = constructor.newInstance(channelSftp, "file1.txt", null);
I found original code here
Success story sharing
ZShape
static
totally defeats the purpose of what he's trying to do, which is instantiate a copy ofZShape
.static
makes it easier, not harder.ZShape myShape = new Shape().instantiateZShape();
. It implies the ZShape you get does not exist without a Shape, which is the intent here.