Çevreleyen bir sınıf Java değil


366

Bir Tetris oyunu yapmaya çalışıyorum ve derleyici hatası alıyorum

Shape is not an enclosing class

bir nesne yaratmaya çalıştığımda

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

Her şekil için iç sınıflar kullanıyorum. İşte kodumun bir parçası

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

Neyi yanlış yapıyorum ?


160
new Shape().new ZShape();. Sınıfın ZShapesomutlaştırılması için bir ek örneği gerekir.
Sotirios Delimanolis

4
iç sınıfı ayrı bir dosyaya
taşı

@Dimmduh yorumu bu durumda cevap olmalıdır. İç sınıflar olmamalılar. Onları taşımak, var olan Shape sınıfıyla ilgili diğer sorunları belirler.
Jeremiah Adams

Buradaki soruyu cevaplamamak için ama burada kalıtım kullanmayı AShapeve ZShapetemel sınıfı genişletmeyi önerebilir miyim Shapes. Sınıfları yerleştirmek bu sorun için gerçekten iyi bir tasarım değildir.
Paramvir Singh Karwal

Yanıtlar:


492

ZShape statik değildir, bu nedenle dış sınıfın bir örneğini gerektirir.

En basit çözüm ZShape ve yapabileceğiniz herhangi bir iç içe sınıf yapmaktır static.

Ben de herhangi bir alan yapmak finalveya ben de yapabilirsiniz static final.


13
Yapımı ZShape statictamamen o bir kopyasını örneğini olan yapmaya çalıştığı şey anlamını ortadan kaldırır ZShape.
Cardano

17
@ Cardano staticbunu kolaylaştırır, zorlaştırır.
Peter Lawrey

12
Başka basit bir çözüm ZShape bu şekilde elde çevreleyen sınıf örneğini iç sınıf, yani yapmaktır: ZShape myShape = new Shape().instantiateZShape();. Aldığınız ZShape'in, burada amaç olan bir Şekil olmadan var olmadığını ima eder.
Vince

@Peter Lawrey Tüm Shape örneklerinin aynı ZShape'i kullanması gerektiğini nasıl anladınız? Kaynağından almıyorum.
İnanılmaz Ocak

2
Statik veya bir örnek istiyorsak 2 durum vardır. Statik yapmak her zaman yardımcı olmaz.
Yogesh Chuahan

177

RetailerProfileModel'in Ana sınıfınız olduğunu ve RetailerPaymentModel'in içindeki bir iç sınıf olduğunu varsayalım. Inner sınıfının sınıf dışında bir nesneyi aşağıdaki gibi oluşturabilirsiniz:

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

34
Bu cevap gerçekten yardımcı oldu, arka arkaya iki kez yeni arayabileceğinizi hiç bilmiyordum (ve 8+ yıldır java yaptım!)
PaulBGD

1
Söz konusu nesnenin referansını tutmak istemediğiniz sürece, yeni operatörü istediğiniz kadar çağırabilirsiniz.
Vishal Kumar

1
Eğer iç sınıfın bir nesnesi bu şekilde oluşturulursa, dış sınıfın üyelerine nasıl erişir?
Xingang Huang

1
İç sınıfın içinde, OuterClass.this'i kullanabilirsiniz. Örneği iç sınıfın kodunun dışından almanın bir yolu olduğunu düşünmüyorum. Tabii ki, her zaman kendi mülkünüzü tanıtabilirsiniz: public OuterClass getOuter () {return OuterClass.this; }
Vishal Kumar

Testler için çalışır:underTest = Mockito.mock(Outer.class).new InnerNonStaticClass();
felvhage

48

Ne önerebilirim statik olmayan sınıfı statik bir sınıfa dönüştürmüyor çünkü bu durumda iç sınıfınız dış sınıfın statik olmayan üyelerine erişemiyor.

Misal :

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

Bu durumda, böyle bir şey yapabilirsiniz:

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

Outer.Inner obj = (yeni Outer) .new Inner ();
Hussain KMR Behestee

1
@HussainKMRBehestee, hayır, bu kesinlikle işe yaramaz. Ancak, bu işe Outer.Inner obj = new Outer().new Inner();
yarar

Ama Amit, benim için çalışıyor. Neden çalışmaması gerektiğini açıklayabilirseniz sevinirim.
Hussain KMR Behestee

1
@HussainKMRBehestee, açıklama: Sadece Java'daki dilbilgisinin bir sınıfı somutlaştırmak için kurucuyu çağırmamız gerektiğini ve kurucuyu çağırırken zorunlu olduğunu söylediğini tahmin edebilirim (). Ancak, C, C ++ bir zorunluluk değildir. İşte işe yaramayan bir örnek. Üstelik bu yazıyı buldum . Java'daki dilbilgisi ve bunların nasıl ayrıştırıldığı hakkında daha fazla bilgi. Bu sözdizimi sizin için çalıştığında örnek bir örnek görmek isterim.
Amit Upadhyay

1
Oh, benim hatam, bir yazım hatasıydı, Dış.İç obj = (yeni Dış ()) .yeni İç (); Umarım bu kez tamam ve bunu fark ettiğiniz için teşekkürler.
Hussain KMR Behestee

18

Dokümanlarda belirtildiği gibi :

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

Bu bağlantı soruyu cevaplayabilse de, cevabın önemli kısımlarını buraya eklemek ve bağlantıyı referans olarak sağlamak daha iyidir. Bağlantı verilen sayfa değişirse, yalnızca bağlantı yanıtları geçersiz olabilir. - Yorumdan
Muhammad Omer Aslam

Teşekkürler! Yeni başladık.
Brennan Miller

10

Bazen, ana sınıfın bazı global değişkenlerine bağlı olduğu için statik olamaz, yeni bir iç sınıf örneği oluşturmamız gerekir. Bu durumda, statik olmayan bir iç sınıf örneği oluşturmaya çalışırsanız,not an enclosing class hata atılır.

Soru örneğini alırsak, ZShapestatik olamazsa küreselShape sınıfın ?

Yeni örneğini nasıl oluşturabilirsiniz? ZShape ? Bu nasıl:

Üst sınıfa bir alıcı ekleyin:

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

Bu şekilde erişin:

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


1

Aynı sorunla karşılaştım. Her iç sınıf için örnek oluşturarak çözdüm. durumunuza gelince, iç sınıflar dışında kalıtım kullanmanızı öneririm.

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
}

o zaman yeni Shape (); ve şekil aracılığıyla ZShape'i ziyaret edin. zShape;


1
Yanlış bir çözüm. Mantıksal hata. İç sınıf (örn. ZShape) herhangi bir alanın ayarlanmasını gerektiriyorsa, dış sınıfın yapıcısında bunu almalısınız! public Shape (Dize field1_innerClass, int field2_innerClass ...) {zShape = yeni ZShape (Dize field1_innerClass, int field2_innerClass ...) ...}}
Mohsen Abasi

1

İç içe sınıfın statik olarak yapılmasına gerek yoktur, ancak herkese açık olmalıdır

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

1

İlk başta kabul edilen cevabı okurken fark etmediğim bir şey, bir iç sınıfı statik hale getirmenin, onu kendi ayrı sınıfına taşımakla aynı şey olmasıydı.

Böylece, hatayı alırken

xxx çevreleyen bir sınıf değil

Aşağıdaki yollardan biriyle çözebilirsiniz:

  • Ekle staticAnahtar kelimeyi iç sınıfa veya
  • Kendi ayrı sınıfına taşıyın.

1

Ana sınıfın tek ton olması durumunda aşağıdaki yolu kullanın:

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

Burada getInstance()üst sınıf singleton nesnesi döndürülür.


0

Sorudan şartı elde etmek için sınıfları arayüze koyabiliriz:

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

ve daha önce denediğiniz yazar olarak kullanın:

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

Uygun "mantıksal" çözümü arıyorsanız, fabrictasarım deseni kullanılmalıdır

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.