包含クラスJavaではありません


366

テトリスゲームを作ろうとしていますが、コンパイラエラーが発生します

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 {
    }
}

何が悪いのですか?


160
new Shape().new ZShape();。クラスZShapeをインスタンス化するには、囲んでいるインスタンスが必要です。
Sotirios Delimanolis 2013年

4
内部クラスを別のファイルに移動
Dimmduh 2017年

この場合、@ Dimmduhコメントが答えになるはずです。それらは内部クラスであってはなりません。それらを移動すると、Shapeクラスに存在する他の問題が識別されます。
エレミヤアダムス

ここで質問に答えるのではなく、ここで継承を使用して基本クラスAShapeZShape拡張することを提案できShapesますか?クラスを入れ子にすることは、この問題にとって本当に良い設計ではありません。
Paramvir Singh Karwal

回答:


492

ZShape 静的ではないため、外部クラスのインスタンスが必要です。

最も簡単な解決策は、可能であればZShapeとネストされたクラスを作成staticすることです。

私はまた、すべてのフィールドになるだろうfinalか、static finalあなたにもできること。


13
作成ZShape staticすると、彼がやろうとしている目的が完全に無効になります。これは、のコピーをインスタンス化したものですZShape
Cardano 2014

17
@Cardanoを使用staticすると、難しくはなく、簡単になります。
Peter Lawrey、2014

12
別の簡単な解決策は、囲んでいるクラスに内部クラスをインスタンス化させることですZShape myShape = new Shape().instantiateZShape();。つまり、ZShapeを次のように取得します。これは、取得したZShapeがShapeなしでは存在しないことを意味します。
ビンス、

@Peter LawreyすべてのShapeインスタンスが同じZSh​​apeを使用する必要があることをどのようにして知りましたか?私は彼のソースからそれを取得しません。
信じられないほどの月

2
静的またはインスタンスが必要な場合は2つのケースがあります。それを静的にすることは常に助けにはなりません。
Yogesh Chuahan

177

RetailerProfileModelがメインクラスで、RetailerPaymentModelがその内部クラスであるとします。次のようにして、クラスの外側にInnerクラスのオブジェクトを作成できます。

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

34
この回答は本当に役に立ちました。続けてnewを2回呼び出すことができるなんて知りませんでした(そして、私は8年以上Javaをやってきました!)
PaulBGD

1
そのオブジェクトの参照を保持したくないまで、確実に何度でもnew演算子を呼び出すことができます。
Vishal Kumar

1
内部クラスのオブジェクトがこの方法で作成された場合、どのようにして外部クラスのメンバーにアクセスしますか?
Xingang Huang

1
内部クラス自体の中で、OuterClass.thisを使用できます。内部クラスのコードの外部からインスタンスを取得する方法はないと思います。もちろん、いつでも独自のプロパティを導入できます。public OuterClass getOuter(){return OuterClass.this; }
Vishal Kumar

テストに使用できます:underTest = Mockito.mock(Outer.class).new InnerNonStaticClass();
felvhage 2018

48

私が提案するのは、非静的クラスを静的クラスに変換しないことです。その場合、内部クラスは外部クラスの非静的メンバーにアクセスできません。

例:

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

したがって、そのような場合、次のようなことができます:

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

Outer.Innerについてはどうですかobj =(new Outer).new Inner();
フセインKMR Behestee 2017

1
@HussainKMRBehestee、それは確かにうまくいきません。しかし、これは機能しますOuter.Inner obj = new Outer().new Inner();
Amit Upadhyay

しかし、アミット、それは私のために働きます。それが機能しない理由を説明していただければ幸いです。
フセインKMR Behestee 2017

1
@HussainKMRBehestee、説明:Javaの文法では、クラスをインスタンス化するためにコンストラクターを呼び出す必要があり、コンストラクターの呼び出し中に()は必須であるとしか推測できません。ただし、C、C ++は必須ではありません。以下は動作しない例です。また、この投稿を見つけました。これは、Javaの文法とそれらの構文解析方法について詳しく説明しています。この構文が機能する場合のサンプルケースをご覧ください。
Amit Upadhyay 2017

1
ああ、私の悪い、それはタイプミスでした、Outer.Inner obj =(new Outer())。new Inner(); 今回は問題ないことを願っています。
フセインKMR Behestee 2017

18

ドキュメントに記載されているように:

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

このリンクで質問に答えることができますが、回答の重要な部分をここに含め、参照用のリンクを提供することをお勧めします。リンクされたページが変更されると、リンクのみの回答が無効になる可能性があります。- レビューから
Muhammad Omer Aslam

ありがとう!始めたばかり。
ブレナンミラー

10

親クラスの一部のグローバル変数に依存するため、静的にできない内部クラスの新しいインスタンスを作成する必要がある場合があります。その場合、静的でない内部クラスのインスタンスを作成しようとすると、not an enclosing classエラーがスローされます。

質問の例をとると、クラスのZShapeグローバル変数が必要なので静的にできない場合はどうなりますShapeか?

の新しいインスタンスをどのように作成できますZShapeか?こうやって:

親クラスにゲッターを追加します。

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

次のようにアクセスします。

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


1

同じ問題が発生しました。すべての内部パブリッククラスのインスタンスを作成することで解決しました。あなたの状況については、内部クラス以外の継承を使用することをお勧めします。

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(); そしてshape.zShapeを介してZShapeをご覧ください。


1
間違った解決策。論理エラー。内部クラス(ZShapeなど)でフィールドを設定する必要がある場合は、外部クラスのコンストラクターで取得する必要があります。public Shape(String field1_innerClass、int field2_innerClass ...){zShape = new ZShape(String field1_innerClass、int field2_innerClass ...)...}}
Mohsen Abasi

1

ネストされたクラスを静的にする必要はありませんが、パブリックでなければなりません

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

1

受け入れられた回答を読んだときに最初に気づかなかったことの1つは、内部クラスを静的にすることは、基本的にそれを独自の別のクラスに移動することと同じことでした。

したがって、エラーが発生したとき

xxxは包含クラスではありません

次のいずれかの方法で解決できます。

  • static内部クラスにキーワードを追加する、または
  • 独自の別のクラスに移動します。

1

Parentクラスがシングルトンの場合は、次の方法を使用します。

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

どこgetInstance()の親クラスのシングルトンオブジェクトを返します。


0

質問からの要件を達成するために、クラスをインターフェースに入れることができます:

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

次に、以前に試した著者として使用します。

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

適切な「論理」ソリューションを探している場合は、fabric設計パターンを使用する必要があります

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.