Не является закрывающим классом Java

Я пытаюсь сделать игру Tetris и получаю ошибку компилятора

Shape is not an enclosing class

когда я пытаюсь создать объект

public class Test {
    public static void main(String[] args) {
        Shape s = new Shapes.ZShape();
    }
}

Я использую внутренние классы для каждой фигуры. Здесь часть моего кода

public class Shapes {
    class AShape {
    }
    class ZShape {
    }
}

Что я делаю не так?

Ответ 1

ZShape не является статическим, поэтому требуется экземпляр внешнего класса.

Самое простое решение - сделать ZShape и любой вложенный класс static, если вы можете.

Я также сделал бы любые поля final или static final, которые вы также можете сделать.

Ответ 2

Предположим, что RetailerProfileModel - это ваш главный класс, а RetailerPaymentModel - это внутренний класс внутри него. Вы можете создать объект класса Inner вне класса следующим образом:

RetailerProfileModel.RetailerPaymentModel paymentModel
        = new RetailerProfileModel().new RetailerPaymentModel();

Ответ 3

Я бы предложил не преобразовать нестатический класс в статический класс, потому что в этом случае ваш внутренний класс не сможет получить доступ к нестационарным членам внешнего класса.

Пример:

class Outer
{
    class Inner
    {
        //...
    }
}

Итак, в таком случае вы можете сделать что-то вроде:

Outer o = new Outer();
Outer.Inner obj = o.new Inner();

Ответ 4

Как указано в документах:

OuterClass.InnerClass innerObject = outerObject.new InnerClass();

Ответ 5

Иногда нам нужно создать новый экземпляр внутреннего класса, который не может быть статическим, поскольку он зависит от некоторых глобальных переменных родительского класса. В этой ситуации, если вы попытаетесь создать экземпляр внутреннего класса, который не является статическим, выдается ошибка not an enclosing class.

Возьмем пример вопроса: что если ZShape не может быть статическим, потому что ему нужна глобальная переменная класса Shape?

Как вы можете создать новый экземпляр ZShape? Вот как:

Добавьте геттер в родительский класс:

public ZShape getNewZShape() {
    return new ZShape();
}

Получите доступ к нему следующим образом:

Shape ss = new Shape();
ZShape s = ss.getNewZShape();

Ответ 6

Shape shape = new Shape();
Shape.ZShape zshape = shape.new ZShape();

Ответ 7

Я столкнулся с той же проблемой. Я решил создать экземпляр для каждого внутреннего публичного класса. что касается ситуации, я предлагаю вам использовать наследование, отличное от внутренних классов.

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
}

то вы можете новый Shape(); и зайдите в ZShape через shape.zShape;

Ответ 8

Не нужно делать вложенный класс статичным, но он должен быть общедоступным

public class Test {
    public static void main(String[] args) {
        Shape shape = new Shape();
        Shape s = shape.new Shape.ZShape();
    }
}

Ответ 9

Если родительский класс одноэлементный, используйте следующий способ:

Parent.Child childObject = (Parent.getInstance()).new Child();

где getInstance() вернет одноэлементный объект родительского класса.

Ответ 10

Одна вещь, которую я не понимал вначале, когда читал принятый ответ, заключался в том, что создание статического класса внутри - это в основном то же самое, что перенос его в отдельный класс.

Таким образом, при получении ошибки

xxx не является охватывающим классом

Вы можете решить эту проблему одним из следующих способов:

  • Добавьте ключевое слово static во внутренний класс или
  • Переместить его в отдельный класс.

Ответ 11

Чтобы выполнить требование из вопроса, мы можем поместить классы в интерфейс:

public interface Shapes {
    class AShape{
    }
    class ZShape{
    }
}

а затем использовать, как автор пытался раньше:

public class Test {
    public static void main(String[] args) {
        Shape s = new Shapes.ZShape();
    }
}

Если мы ищем правильное "логическое" решение, следует использовать fabric шаблон проектирования