Java - Foo türünde bir kapatma örneğine erişilemiyor


314

Takip koduna sahibim:

class Hello {
    class Thing {
        public int size;

        Thing() {
            size = 0;
        }
    }

    public static void main(String[] args) {
        Thing thing1 = new Thing();
        System.out.println("Hello, World!");
    }
}

Biliyorum Thinghiçbir şey yapmaz, ama Merhaba, Dünya programım onsuz iyi derler. Benim üzerimde sadece tanımlanmış sınıflarım var.

Ve derlemeyi reddediyor. Ben olsun No enclosing instance of type Hello is accessible."yeni Şey oluşturur çizgisinde. Ben de tahmin ediyorum:

  1. Sistem düzeyinde sorun yaşıyorum (DrJava veya Java kurulumumda) veya
  2. Java'da bir çalışma programının nasıl oluşturulacağına dair bazı temel yanlış anlaşılmalar var.

Herhangi bir fikir?


Yanıtlar:


483

static class Thing programınızın çalışmasını sağlayacaktır.

Olduğu gibi, sahip olduğun Thing(tanımı gereği) belirli bir örneğiyle ilişkili bir iç sınıf olarak Hellosöylemek bir hata olduğu anlamına gelir (kullandığı asla bile veya ona atıfta), new Thing();belirli bir kalmadan Helloörneği içinde dürbün.

Bunun yerine statik bir sınıf olarak bildirirseniz, belirli bir Helloörneğe ihtiyaç duymayan "iç içe" bir sınıftır .


Bu aynı zamanda outer class, somutlaştırırsam non-static inner classhiçbir yerde kullanmasam bile yaratılacağı anlamına mı geliyor ?
mr5

Hayır. Bir iç sınıftaki her nesnenin bir ebeveyni olmalıdır, ancak bir ebeveyni 0 dahil olmak üzere herhangi bir sayıda çocuğa sahip olabilir.
jacobm

92

Sınıfı Thingstatik olmayan bir iç sınıf olarak ilan ettiniz . Bu, Hellosınıfın bir örneğiyle ilişkilendirilmesi gerektiği anlamına gelir .

Kodunuzda, Thingstatik bir bağlamdan bir örnek oluşturmaya çalışıyorsunuz . Derleyici bundan şikayet ediyor.

Birkaç olası çözüm var. Hangi çözümü kullanacağınız neyi başarmak istediğinize bağlıdır.

  • Taşı Thingdışına Hellosınıfına.

  • İç içe bir sınıf Thingolarak değiştirin static.

    static class Thing
  • Oluşturma bir örneğini ait Hellobir örneğini oluşturmadan önce Thing.

    public static void main(String[] args)
    {
        Hello h = new Hello();
        Thing thing1 = h.new Thing(); // hope this syntax is right, typing on the fly :P
    }

Son çözüm ( statik olmayan iç içe bir sınıf), anlamlı olacak Thingbir örneğe bağlıysa, zorunlu olacaktır Hello. Örneğin, eğer:

public class Hello {
    public int enormous;

    public Hello(int n) {
        enormous = n;
    }

    public class Thing {
        public int size;

        public Thing(int m) {
            if (m > enormous)
                size = enormous;
            else
                size = m;
        }
    }
    ...
}

sınıftaki bir nesneyi oluşturmak için herhangi bir ham girişim Thing:

Thing t = new Thing(31);

sorunlu olurdu, çünkü enormous31'i buna karşı test etmek için bariz bir değer olmazdı . Bu değeri sağlamak hiçin Hellodış sınıfın bir örneği gereklidir h.enormous:

...
Hello h = new Hello(30);
...
Thing t = h.new Thing(31);
...

Bir gelmez Çünkü Thingbu bir yoksa Hello.

İç içe / iç sınıflar hakkında daha fazla bilgi için: İç içe Sınıflar (Java Öğreticileri)


Cevabınız hem kapsamlı hem de sentetik. En azından bana garip gelse bile, sözdizimi doğrudur.
boumbh

Birisi hala hata alıyorsa, sözdizimi Thing thing1 <<HelloInstantiation>>.new Thing()anahtardır. Sözdizimini kullanarak birkaç dakika karıştı Thing thing1 new <<HelloInstantiation>>.Thing(). = P
skia.heliou

1
@ skia.heliou Teşekkürler! Yardımcı bir sınıf yapıyordum ve statik değişkenler (hatta sınıflar) sadece kapsamı ortadan kaldırmakla kalmıyor, aynı zamanda genellikle verimsiz oluyorlardı. Çalışma zamanı argümanları sağlaması, ana yöntemi kullanma zahmetine neden olur. Tüm ihtiyacım olan şey ve tam olarak bulmak istediğim şeydi.
Terk Edilmiş Sepet

25

Pekala ... pek çok iyi cevap ama daha fazlasını eklemek istiyorum. Java-Java'daki Inner sınıfına kısa bir bakış, başka bir sınıf içindeki bir sınıfı tanımlamamıza olanak tanır ve sınıfları bu şekilde yuvalayabilmenin bazı avantajları vardır:

  1. Bu olabilir (Bu kapsülleme artırır) gizlemek sınıf yalnızca içinde bulunur sınıfı tarafından kullanılıyorsa, özellikle ilgili - başka sınıflardan sınıf. Bu durumda dış dünyanın bunu bilmesi gerekmez.

  2. Sınıflar mantıksal olarak ihtiyaç duydukları yerde gruplandığından kodu daha sürdürülebilir hale getirebilir .

  3. İç sınıf, içerdiği sınıfın örnek değişkenlerine ve yöntemlerine erişime sahiptir .

Biz esas olarak üç çeşit Inner Classes

  1. Yerel iç
  2. Statik İç Sınıf
  3. Anonim İç Sınıf

Unutulmaması gereken önemli noktalardan bazıları

  • İçinde bulunduğu Yerel İç Sınıf'a erişmek için sınıf nesnesine ihtiyacımız var.
  • Statik İç Sınıf, var olduğu sınıfın diğer statik yöntemlerine benzer şekilde doğrudan erişilir.
  • Anonim İç Sınıf, dış dünyaya olduğu gibi aynı sınıfın (içinde bulunduğu) diğer yöntemlere veya sınıflara da görünmez ve bildirildiği noktada kullanılır.

Yukarıdaki kavramları pratikte görmeye çalışalım_

public class MyInnerClass {

public static void main(String args[]) throws InterruptedException {
    // direct access to inner class method
    new MyInnerClass.StaticInnerClass().staticInnerClassMethod();

    // static inner class reference object
    StaticInnerClass staticInnerclass = new StaticInnerClass();
    staticInnerclass.staticInnerClassMethod();

    // access local inner class
    LocalInnerClass localInnerClass = new MyInnerClass().new LocalInnerClass();
    localInnerClass.localInnerClassMethod();

    /*
     * Pay attention to the opening curly braces and the fact that there's a
     * semicolon at the very end, once the anonymous class is created:
     */
    /*
     AnonymousClass anonymousClass = new AnonymousClass() {
         // your code goes here...

     };*/
 }

// static inner class
static class StaticInnerClass {
    public void staticInnerClassMethod() {
        System.out.println("Hay... from Static Inner class!");
    }
}

// local inner class
class LocalInnerClass {
    public void localInnerClassMethod() {
        System.out.println("Hay... from local Inner class!");
    }
 }

}

Umarım bu irade herkese yardımcı olur. Daha fazla bilgi için lütfen başvurun


Önerilen geliştirmeler: birinci sınıf MyOuterClass olarak adlandırın, yorumları AnonymousClass'tan kaldırın.
Noumenon


9

Bunu aşağıdaki basit örnekle anlayalım. Bunun nedeni, STATİK OLMAYAN İÇ İÇ SINIFI olmasıdır. Dış sınıf örneğine ihtiyacınız var.

 public class PQ {

    public static void main(String[] args) {

        // create dog object here
        Dog dog = new PQ().new Dog();
        //OR
        PQ pq = new PQ();
        Dog dog1 = pq.new Dog();
    }

    abstract class Animal {
        abstract void checkup();
    }

    class Dog extends Animal {
        @Override
        void checkup() {
            System.out.println("Dog checkup");

        }
    }

    class Cat extends Animal {
        @Override
        void checkup() {
            System.out.println("Cat Checkup");

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