it-swarm-tr.com

Java iç sınıfı ve statik iç içe sınıf

Java'da iç sınıf ile statik iç içe sınıf arasındaki temel fark nedir? Tasarım/uygulama bunlardan birini seçmede rol oynuyor mu?

1585
Omnipotent

Java Eğitiminden :

İç içe sınıflar iki kategoriye ayrılır: statik ve statik olmayan. Statik olarak bildirilen iç içe sınıflar, yalnızca statik iç içe sınıflar olarak adlandırılır. Statik olmayan iç içe sınıflara iç sınıflar denir. 

Statik iç içe sınıflara ekteki sınıf adı kullanılarak erişilir:

OuterClass.StaticNestedClass

Örneğin, statik iç içe sınıf için bir nesne oluşturmak için bu sözdizimini kullanın:

OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();

Bir iç sınıfın örnekleri olan nesneler dış sınıfın bir örneği içinde bulunur. Aşağıdaki sınıfları göz önünde bulundurun:

class OuterClass {
    ...
    class InnerClass {
        ...
    }
}

Bir InnerClass örneği, yalnızca bir OuterClass örneği içinde var olabilir ve onu kapsayan örneğinin yöntemlerine ve alanlarına doğrudan erişebilir.

Bir iç sınıfı örneklemek için, önce dış sınıfı örneklemelisiniz. Daha sonra, bu sözdizimiyle dış nesnenin içindeki iç nesneyi oluşturun:

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

bakınız: Java Eğitimi - İç İçe Sınıflar

Bütünlüğü sağlamak için ayrıca iç sınıf olmadan çevreleyen bir örnek şeklinde bir şey olduğunu unutmayın.

class A {
  int t() { return 1; }
  static A a =  new A() { int t() { return 2; } };
}

Burada, new A() { ... } bir statik bağlamda tanımlanan iç sınıf 'dır ve çevreleyen bir örneği yoktur.

1564
Martin

Yukarıdaki cevaplarda gerçek farkın belirginleştiğini sanmıyorum. 

Öncelikle şartları doğrula: 

  • Yuvalanmış bir sınıf, kaynak kod düzeyinde başka bir sınıfta bulunan bir sınıftır.
  • static modifier ile bildirirseniz statiktir.
  • Statik olmayan iç içe bir sınıfa iç sınıf denir. (Statik olmayan iç içe sınıfla kalıyorum.)

Martin'in cevabı şimdiye kadar doğru. Ancak, asıl soru şudur: Yuvalanmış bir sınıfı statik ilan etmenin veya bildirmemenin amacı nedir?

statik iç içe sınıfları kullanırsınız eğer sınıflarınızı topikal olarak birleştiriyorlarsa veya iç içe geçmiş sınıf yalnızca dışlayıcı sınıfta kullanılıyorsa, sınıflarınızı bir arada tutmak istiyorsanız. Statik iç içe sınıf ile diğer her sınıf arasında anlamsal bir fark yoktur.

Statik olmayan iç içe sınıflar farklı bir canavardır. Anonim iç sınıflara benzer şekilde, iç içe geçmiş sınıflar aslında kapanışlardır. Bu, çevreleyen kapsamlarını ve çevreleyen hallerini ele geçirip bunu erişilebilir kılar. Belki bir örnek bunu açıklığa kavuşturur. Bir Konteynırın bu saplamasına bakın:

public class Container {
    public class Item{
        Object data;
        public Container getContainer(){
            return Container.this;
        }
        public Item(Object data) {
            super();
            this.data = data;
        }

    }

    public static Item create(Object data){
        // does not compile since no instance of Container is available
        return new Item(data);
    }
    public Item createSubItem(Object data){
        // compiles, since 'this' Container is available
        return new Item(data);
    }
}

Bu durumda, bir alt öğeden üst kapsayıcısına bir referans almak istiyorsunuz. Statik olmayan iç içe bir sınıf kullanarak, bu biraz çalışmadan çalışır. Konteynerin örnek örneğine Container.this sözdizimiyle erişebilirsiniz.

Aşağıdaki daha sert açıklamalar:

Java bayt kodlarına bakarsanız, derleyici (statik olmayan) yuvalanmış bir sınıf için oluşturur;

// class version 49.0 (49)
// access flags 33
public class Container$Item {

  // compiled from: Container.Java
  // access flags 1
  public INNERCLASS Container$Item Container Item

  // access flags 0
  Object data

  // access flags 4112
  final Container this$0

  // access flags 1
  public getContainer() : Container
   L0
    LINENUMBER 7 L0
    ALOAD 0: this
    GETFIELD Container$Item.this$0 : Container
    ARETURN
   L1
    LOCALVARIABLE this Container$Item L0 L1 0
    MAXSTACK = 1
    MAXLOCALS = 1

  // access flags 1
  public <init>(Container,Object) : void
   L0
    LINENUMBER 12 L0
    ALOAD 0: this
    ALOAD 1
    PUTFIELD Container$Item.this$0 : Container
   L1
    LINENUMBER 10 L1
    ALOAD 0: this
    INVOKESPECIAL Object.<init>() : void
   L2
    LINENUMBER 11 L2
    ALOAD 0: this
    ALOAD 2: data
    PUTFIELD Container$Item.data : Object
    RETURN
   L3
    LOCALVARIABLE this Container$Item L0 L3 0
    LOCALVARIABLE data Object L0 L3 2
    MAXSTACK = 2
    MAXLOCALS = 3
}

Gördüğünüz gibi derleyici gizli bir alan oluşturur Container this$0. Bu, ek örneğini belirtmek için ek bir Container tipi parametresi olan kurucuda ayarlanır. Bu parametreyi kaynakta göremezsiniz ancak derleyici iç içe geçmiş bir sınıf için örtük olarak oluşturur. 

Martin örneği

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

öyle bir şey için derlenebilir (bayt kodlarında)

new InnerClass(outerObject)

Bütünlüğü uğruna:

Anonim bir sınıf - kendisiyle ilişkilendirilmiş bir adı olmayan ve daha sonra referans alınamayan statik olmayan bir yuvalanmış sınıfın mükemmel bir örneğidir.

131
jrudolph

Yukarıdaki cevapların hiçbirinin size iç içe geçmiş bir sınıfla statik iç içe geçmiş bir sınıf arasındaki uygulama tasarımı açısından gerçek farkı açıklamadığını düşünüyorum: 

Genel bakış

İç içe geçmiş bir sınıf durağan veya statik olmayabilir ve her durumda başka bir sınıf içinde tanımlanmış bir sınıftır. İç içe geçmiş bir sınıf yalnızca hizmet vermek için sınıf içermelidir} _, iç içe geçmiş bir sınıf diğer sınıflar tarafından kullanılabiliyorsa (yalnızca içine alan değil), üst düzey bir sınıf olarak bildirilmelidir.

Fark

Statik Olmayan Sınıflandırılmış sınıf: örtük olarak sınıf içeren çevreleyen örnekle ilişkilendirilir, bu, çevreleyen örneğin yöntemlerini ve erişim değişkenlerini çağırmanın mümkün olduğu anlamına gelir. Statik olmayan iç içe geçmiş bir sınıfın yaygın kullanımı, bir Adaptör sınıfını tanımlamaktır.

Statik İç İçe Sınıf: çevreleyen sınıf örneğine erişemiyor ve bunun üzerine yöntemleri çağırıyor, bu nedenle iç içe sınıf, çevreleyen sınıfın bir örneğine erişmeyi gerektirmediğinde kullanılmalıdır. Statik iç içe sınıfın yaygın bir kullanımı, dış nesnenin bir bileşenlerini uygulamaktır.

Sonuç

Bu nedenle, ikisi arasındaki tasarım açısından ana fark şudur: statik olmayan iç içe sınıf, container sınıfının örneğine erişebilir, statik ise.

88
aleroot

Basit bir ifadeyle, Java'nın kapanmadığı için öncelikle iç içe derslere ihtiyacımız var.

İç İçe Sınıflar, başka bir çevre sınıfının gövdesinde tanımlanan sınıflardır. İki tiptedir - statik ve statik olmayan.

Bunlar, çevreleyen sınıfın üyeleri olarak değerlendirilir, bu nedenle dört erişim belirtecinden herhangi birini belirtebilirsiniz - private, package, protected, public. Bu lüksü yalnızca üst seviye sınıflar olan ve sadece public ya da özel paket ilan edilebilir.

İç sınıflar - Yığın olmayan sınıflar, özel olarak ilan edilmiş olsalar bile, Statik iç içe sınıflar üst sınıfın diğer üyelerine erişemezken, üst sınıftaki diğer üyelere erişebilirler.

public class OuterClass {
    public static class Inner1 {
    }
    public class Inner2 {
    }
}

Inner1 statik iç sınıfımızdır ve Inner2 statik olmayan iç sınıfımızdır. Aralarındaki temel fark, bağımsız bir Inner2 nesnesi oluşturabileceğiniz bir Outer olmadan bir Inner1 örneği oluşturamazsınız.

İç sınıfı ne zaman kullanırsınız?

Class A ve Class B'nun ilişkili olduğu bir durum düşünün, Class BClass A üyelerine erişmelidir ve Class B yalnızca Class A ile ilgilidir. İç sınıflar resmin içine giriyor.

Bir iç sınıf örneği oluşturmak için, dış sınıfınızın bir örneğini oluşturmanız gerekir.

OuterClass outer = new OuterClass();
OuterClass.Inner2 inner = outer.new Inner2();

veya

OuterClass.Inner2 inner = new OuterClass().new Inner2();

Statik İç sınıfı ne zaman kullanırsınız?

Statik bir iç sınıf tanımlayacaksınız, bunu çevreleyen sınıf/üst sınıf örneği ile herhangi bir ilişkisi olmadığını bileceksiniz. İç sınıfınız dış sınıfın yöntemlerini veya alanlarını kullanmıyorsa, bu sadece bir alan kaybıdır, bu yüzden onu statik hale getirin.

Örneğin, statik iç içe sınıf için bir nesne oluşturmak için bu sözdizimini kullanın:

OuterClass.Inner1 nestedObject = new OuterClass.Inner1();

Statik yuvalanmış bir sınıfın avantajı, çalışmak için içeren sınıf/üst sınıfın bir nesnesine ihtiyaç duymamasıdır. Bu, uygulamanızın çalışma zamanında oluşturduğu nesne sayısını azaltmanıza yardımcı olabilir.

31
Thalaivar

Genel olarak takip edilen konvansiyonun bu olduğunu düşünüyorum:

  • statik sınıf bir üst seviye sınıf içindeki yuvalanmış sınıf
  • statik olmayan sınıf bir üst seviye sınıf içinde iç sınıf.
    • local class - bir yöntem veya yapıcı gövdesi gibi bir bloğun içinde bildirilen sınıflar
    • anonim sınıf - örnekleri ifadelerde ve ifadelerde oluşturulan adsız sınıflar

Bununla birlikte, birkaç başka hatırlayan nokta:

  • Üst düzey sınıflar ve statik iç içe geçmiş sınıf, statik iç içe geçmiş sınıf durumunda, Outer [parent] sınıfının özel statik alanlarına/yöntemlerine statik başvuru yapabilir ve bunun tersi de geçerlidir.

  • İç sınıflar, Outer [parent] sınıfının ekli örneğinin örnek değişkenlerine erişebilir. Bununla birlikte, tüm iç sınıfların çevreleyen örnekleri yoktur, örneğin statik bir başlatıcı bloğunda kullanılan anonim bir sınıf gibi statik bağlamdaki iç sınıflar yoktur.

  • Anonim sınıf, varsayılan olarak ebeveyn sınıfını genişletir veya ebeveyn arayüzünü uygular ve başka bir sınıfı genişletmek veya başka arayüzler uygulamak için başka bir madde yoktur. Yani,

    • new YourClass(){};class [Anonymous] extends YourClass {} anlamına gelir
    • new YourInterface(){};class [Anonymous] implements YourInterface {} anlamına gelir

Açık kalan en büyük sorunun hangisini ne zaman kullanacağını hissediyorum? Bu, çoğunlukla hangi senaryo ile uğraştığınıza bağlıdır, ancak @jududolph tarafından verilen cevabı okumak bazı kararlar vermenize yardımcı olabilir.

26
sactiw

Java iç sınıfı ve statik iç içe sınıf arasındaki temel farklar ve benzerlikler aşağıdadır.

Umarım yardımcı olur!

İç sınıf

  • Erişebilir dış sınıfa hem örnek hem de statik yöntem ve alan
  • Onu içine alan sınıfın örneğiyle ilişkilendirilir öyleyse, onu başlatmak için önce bir dış sınıf örneğine ihtiyaç duyar (not new anahtar sözcük yeri):

    Outerclass.InnerClass innerObject = outerObject.new Innerclass();
    
  • Cannot herhangi bir _ tanımlayabilir statik üyeler

  • Cannot, Sınıf veya Arayüz bildirgesine sahip

Statik iç içe sınıf

  • Erişilemiyor dış sınıf örnek yöntem veya alan

  • Herhangi bir çevre sınıfı örneği ile ilişkili değil Öyleyse bunu başlatmak için:

    OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
    

Benzerlikler

  • Her ikisi de İç sınıflar, özel alanlar ve yöntemler/dış sınıf bile erişebilir
  • Ayrıca Dış sınıf, özel alanlar ve yöntemler/iç sınıflar erişimine de sahiptir.
  • Her iki sınıfın da özel, korumalı veya herkese açık erişim değiştiricisi olabilir

Neden İç İçe Sınıflar Kullanmalı?

Oracle belgelerine göre çeşitli nedenler vardır ( tam belgeler ):

  • Yalnızca bir yerde kullanılan sınıfları mantıksal olarak gruplandırma yöntemi: Eğer bir sınıf yalnızca bir sınıfa faydalıysa, o sınıfa gömmek ve ikisini bir arada tutmak mantıklıdır. Bu tür "yardımcı sınıfları" yerleştirmek, paketlerini daha düzenli hale getirir.

  • Kapsüllemeyi artırır: B ve A'nın B üyelerine erişime ihtiyaç duyduğu, diğer bir deyişle özel ilan edilecek iki üst seviye sınıfı düşünün. A sınıfındaki B sınıfını gizleyerek, A'nın üyeleri özel ilan edilebilir ve B bunlara erişebilir. Ayrıca, B'nin kendisi dış dünyadan gizlenebilir.

  • Daha okunaklı ve bakım gerektirebilir kodlara yol açabilir: Küçük sınıfları en üst düzey sınıflara yerleştirmek, kodu kullanıldığı yere yaklaştırır.

26
Behzad Bahmanyar

İç içe sınıf: sınıf içindeki sınıf

Türleri:

  1. Statik iç içe sınıf
  2. Statik olmayan iç içe sınıf [İç sınıf]

Fark:

Statik olmayan iç içe sınıf [İç sınıf]

Statik olmayan iç içe sınıfta iç sınıf nesnesi dış sınıf nesnesi içinde bulunur. Böylece dış sınıfa ait veri üyesine iç sınıfa erişilebilir. Bu yüzden iç sınıf nesnesini yaratmak için önce dış sınıf nesnesini yaratmalıyız.

outerclass outerobject=new outerobject();
outerclass.innerclass innerobjcet=outerobject.new innerclass(); 

Statik iç içe sınıf

İç sınıfın statik iç içe sınıf nesnesinde, dış sınıf nesnesine ihtiyaç duyulmaz, çünkü "statik" sözcüğü nesne oluşturmaya gerek olmadığını gösterir.

class outerclass A {
    static class nestedclass B {
        static int x = 10;
    }
}

X'e erişmek istiyorsanız, aşağıdaki yöntemi yazın

  outerclass.nestedclass.x;  i.e. System.out.prinltn( outerclass.nestedclass.x);
15
tejas

Bazı durumlarda yararlı olabilecek iç içe statik sınıfların kullanımı hakkında bir incelik vardır.

Statik nitelikler, sınıf kurucu aracılığıyla başlatılmadan önce somutlaştırılmışken,... İlk önce atıfta bulunulur, 'final' olarak işaretlenmiş olsalar bile.

Bu örneği düşünün:

public class C0 {

    static C0 instance = null;

    // Uncomment the following line and a null pointer exception will be
    // generated before anything gets printed.
    //public static final String outerItem = instance.makeString(98.6);

    public C0() {
        instance = this;
    }

    public String makeString(int i) {
        return ((new Integer(i)).toString());
    }

    public String makeString(double d) {
        return ((new Double(d)).toString());
    }

    public static final class nested {
        public static final String innerItem = instance.makeString(42);
    }

    static public void main(String[] argv) {
        System.out.println("start");
        // Comment out this line and a null pointer exception will be
        // generated after "start" prints and before the following
        // try/catch block even gets entered.
        new C0();
        try {
            System.out.println("retrieve item: " + nested.innerItem);
        }
        catch (Exception e) {
            System.out.println("failed to retrieve item: " + e.toString());
        }
        System.out.println("finish");
    }
}

'İç içe' ve 'innerItem' her ikisi de 'statik final' olarak ilan edildi. nested.innerItem ayarı. ve yukarıda bahsettiğim satırları yorumlamak. Aynı durum "dış öğe" için de geçerlidir.

En azından Java 6.0'da gördüğüm şey bu.

11
HippoMan

Dış sınıfın örneği oluşturulduğunda iç sınıfın örneği oluşturulur. Bu nedenle, iç sınıfın üyeleri ve yöntemleri, dış sınıfın örneğinin (nesnesinin) üyelerine ve yöntemlerine erişebilir. Dış sınıf örneği kapsam dışına çıktığında, iç sınıf örnekleri de ortadan kalkar.

Statik iç içe sınıfın somut bir örneği yoktur. Sadece ilk kez kullanıldığında yüklenir (statik yöntemler gibi). Metodları ve değişkenleri dış sınıfın örneklerine erişimi olmayan tamamen bağımsız bir varlıktır.

Statik iç içe sınıflar dış nesneyle birleştirilmez, daha hızlıdırlar ve yığın/yığın belleği almazlar, çünkü böyle bir sınıfın örneğini oluşturmak için gerekli değildir. Bu nedenle, temel kural statik yuvalanmış sınıfı, mümkün olduğunca sınırlı kapsamla (private> = class> = korumalı> = public) tanımlamaya çalışmak ve sonra onu ("statik" tanımlayıcıyı kaldırarak) iç sınıfa dönüştürmek ve gevşetmektir. Kapsam, gerçekten gerekliyse.

11
rmaruszewski

Buraya eklenecek çok şey olduğunu sanmıyorum, cevapların çoğu statik iç içe sınıf ile İç sınıflar arasındaki farklılıkları mükemmel bir şekilde açıklıyor. Ancak, iç sınıflara karşı iç içe sınıfları kullanırken aşağıdaki sorunu göz önünde bulundurun. Bir kaç cevapta bahsedildiği gibi, iç sınıflar çevreleme sınıflarının örnekleri olmadan örneklenemezler ve bu onların çevreleme örneğine HOLD a işaretçi anlamına gelir. GC'nin daha fazla kullanılmasalar bile, çevreleyen sınıfları çöp toplayamayacağından dolayı, bellek taşması veya yığın taşması istisnasına yol açabilecek sınıf. Bunu netleştirmek için aşağıdaki kodu kontrol edin: 

public class Outer {


    public  class Inner {

    }


    public Inner inner(){
        return new Inner();
    }

    @Override
    protected void finalize() throws Throwable {
    // as you know finalize is called by the garbage collector due to destroying an object instance
        System.out.println("I am destroyed !");
    }
}


public static void main(String arg[]) {

    Outer outer = new Outer();
    Outer.Inner inner = outer.new Inner();

    // out instance is no more used and should be garbage collected !!!
    // However this will not happen as inner instance is still alive i.e used, not null !
    // and outer will be kept in memory until inner is destroyed
    outer = null;

    //
    // inner = null;

    //kick out garbage collector
    System.gc();

}

// inner = null; hakkındaki yorumu kaldırırsanız program put "Tahrip oldum!" Yazacaktır, ancak bunu yorumlamayacaktır.
Çünkü sebebi, beyaz içsel durumun hala başvurulan olması GC'nin toplayamaması ve toplanamayan dış örneğe de başvuruda bulunması (bir göstericiye sahip olması) nedeniyledir. Projenizde bu nesnelerden yeterince bulunup hafızanız tükenebilir.
İç sınıf örneğine işaret etmeyen statik iç sınıflara kıyasla, bununla ilgili değil sınıfla ilişkilidir. Eğer Inner sınıfını statik kılar ve Outer.Inner i = new Outer.Inner(); ile başlatırsanız yukarıdaki program "tahrip oldum!" Yazdırabilir. 

10
Adelin

Örnek oluşturma durumunda,.. Statik olmayan iç sınıf örneği, tanımlandığı dış sınıfın nesnesine referansla yaratılır. Bu , Kapsayıcı bir örneğe sahip olduğu anlamına gelir .Ama statik iç sınıfın örneği, dış sınıf nesnesi referansı ile değil, dış sınıfın referansı ile yaratılır. Bu demektir ki Kapsayıcı bir örneğe sahip değilsiniz.

Örneğin:

class A
{
  class B
  {
    // static int x; not allowed here…..    
  }
  static class C
  {
    static int x; // allowed here
  }
}

class Test
{
  public static void main(String… str)
  {
    A o=new A();
    A.B obj1 =o.new B();//need of inclosing instance

    A.C obj2 =new A.C();

    // not need of reference of object of outer class….
  }
}
10
Ankit Jain

Terimler birbirlerinin yerine kullanılır. Bu konuda gerçekten bilgili olmak istiyorsanız, olabilir, iç içe geçmiş bir örneği olmayan statik bir sınıfa başvurmak için "iç içe sınıfı" tanımlarsınız. Kodda şöyle bir şey olabilir:

public class Outer {
    public class Inner {}

    public static class Nested {}
}

Bu gerçekten de yaygın olarak kabul gören bir tanım değil.

8
Daniel Spiewak

İç içe geçmiş sınıf çok genel bir terimdir: üst düzey olmayan her sınıf iç içe geçmiş bir sınıftır .. __ İç sınıf, statik olmayan iç içe geçmiş bir sınıftır .. __, Joseph Darcy İç İçe İç , Üye ve Üst Düzey Sınıflar .

8
Wouter Coekaerts

Java ve/veya İç İçe Sınıflara yeni başlayan hedefleme öğrencisi

İç içe sınıflar şunlardan biri olabilir:
1. Statik İç İçe Sınıflar.
2. Statik Olmayan İç İçe Sınıflar. (olarak da bilinir İç sınıflar) => Lütfen bunu unutmayın


1.İç sınıfları
Örnek:

class OuterClass  {
/*  some code here...*/
     class InnerClass  {  }
/*  some code here...*/
}


İç sınıflar iç içe sınıfların altkümeleridir:

  • iç sınıf, belirli bir iç içe sınıf türüdür
  • iç sınıflar iç içe sınıfların altkümeleridir.
  • Bir iç sınıfının da iç içe geçmiş bir sınıf olduğunu söyleyebilirsiniz, ancak şunları yapabilirsiniz NOT iç içe geçmiş bir sınıfın da iç sınıf olduğunu söyleyebilirsiniz .

İç sınıfın uzmanlığı:

  • bir iç sınıfın örneği, “özel” olarak işaretlenmiş olanlar bile olsa, dış sınıf üyelerine herkese erişim sahiptir.


2.Statik İç İçe Sınıflar:
Örnek:

class EnclosingClass {
  static class Nested {
    void someMethod() { System.out.println("hello SO"); }
  }
}

1. Durum: Çevreleyen olmayan bir sınıftan statik iç içe sınıflar oluşturma

class NonEnclosingClass {

  public static void main(String[] args) {
    /*instantiate the Nested class that is a static
      member of the EnclosingClass class:
    */

    EnclosingClass.Nested n = new EnclosingClass.Nested(); 
    n.someMethod();  //prints out "hello"
  }
}

Durum 2: Statik bir yuvalanmış sınıfı çevreleyen bir sınıftan oluşturma

class EnclosingClass {

  static class Nested {
    void anotherMethod() { System.out.println("hi again"); } 
  }

  public static void main(String[] args) {
    //access enclosed class:

    Nested n = new Nested(); 
    n.anotherMethod();  //prints out "hi again"
  }

}

Statik sınıfların uzmanlığı:

  • Statik iç sınıf yalnızca dış sınıfın statik üyelerine erişebilir ve statik olmayan üyelere erişemez.

Sonuç:
Soru: Java’da bir iç sınıf ile iç içe statik sınıf arasındaki temel fark nedir?
Cevap: yukarıda belirtilen her bir sınıfın özelliklerini gözden geçirin.

7
VdeX

Ummm ... bir iç sınıf IS iç içe bir sınıf ... anonim bir sınıf ve iç sınıf mı demek istiyorsun?

Düzenleme: Eğer gerçekten isminizi anonim olarak mı kastediyorsanız ... bir iç sınıf sadece bir sınıf içinde tanımlanmış bir sınıftır:

public class A {
    public class B {
    }
}

Anonim bir sınıf, anonim olarak tanımlanmış bir sınıfın bir uzantısıdır; bu nedenle, fiili olarak bir sınıf tanımlanmaz:

public class A {
}

A anon = new A() { /* you could change behavior of A here */ };

Ek Düzenleme:

Vikipedi bir farkın var olduğunu iddia ediyor Java, ama 8 yıldır Java ile çalışıyorum ve ilk defa böyle bir ayrım duydum ... iddiadan vazgeçmek için hiçbir referans yok. ... alt satırda, bir iç sınıf bir sınıf içinde tanımlanmış bir sınıftır (statik veya değil) ve iç içe geçmiş aynı şeyi ifade eden başka bir terimdir.

Statik ve statik olmayan iç içe sınıf arasında ince bir fark var ... temelde statik olmayan iç sınıflar, örnek alanlara ve çevreleyen sınıfın yöntemlerine dolaysız erişime sahipler (bu nedenle statik bir bağlamda oluşturulamazlar, bir derleyici olacaklar. hata). Öte yandan, statik iç içe sınıflar, örnek alanlara ve yöntemlere dolaysız erişime sahip değildir ve statik bir bağlamda CAN inşa edilebilir.

7
Mike Stone

Inner sınıfı ve nested statik sınıfı Java’nın her ikisi de, Java’daki en üst sınıf olarak bilinen, başka bir sınıf içinde bildirilen sınıflardır. Java terminolojisinde, iç içe geçmiş bir sınıf statik ilan ederseniz, Java'da iç içe statik sınıf olarak adlandırılırken, statik olmayan iç içe sınıf basitçe İç Sınıf olarak adlandırılır. 

Java’daki İç Sınıf nedir?

Üst düzey olmayan veya başka bir sınıf içinde bildirilen herhangi bir sınıf, yuvalanmış sınıf olarak bilinir ve iç içe geçmiş sınıfların dışında, statik olmayan olarak ilan edilen sınıf, Java'da İç sınıf olarak bilinir. Java'da üç tür İç sınıf vardır:

1) Yerel iç sınıf - bir kod bloğu veya yöntemi içerisinde bildirilir.
2) Anonim iç sınıf - oluşturulduğu yerde referans almak ve ilklendirilmek için adı olmayan bir sınıftır.
3) Üye iç sınıfı - dış sınıfa statik olmayan üye olarak bildirilir.

public class InnerClassTest {
    public static void main(String args[]) {      
        //creating local inner class inside method i.e. main() 
        class Local {
            public void name() {
                System.out.println("Example of Local class in Java");

            }
        }      
        //creating instance of local inner class
        Local local = new Local();
        local.name(); //calling method from local inner class

        //Creating anonymous inner class in Java for implementing thread
        Thread anonymous = new Thread(){
            @Override
            public void run(){
                System.out.println("Anonymous class example in Java");
            }
        };
        anonymous.start();

        //example of creating instance of inner class
        InnerClassTest test = new InnerClassTest();
        InnerClassTest.Inner inner = test.new Inner();
        inner.name(); //calling method of inner class
    }

     //Creating Inner class in Java
    private class Inner{
        public void name(){
            System.out.println("Inner class example in Java");
        }
    }
}

Java'da iç içe statik sınıf nedir?

Yuvalanmış statik sınıf, bir sınıf içinde üye olarak bildirilen ve statik yapılan başka bir sınıftır. İç içe statik sınıf ayrıca dış sınıfın üyesi olarak ilan edilir ve diğer üyeler gibi özel, genel veya korunabilir hale getirilebilir. İç içe statik sınıfın iç sınıfa göre en büyük yararlarından biri, iç içe statik sınıf örneğinin, herhangi bir Outer sınıfı örneğine eklenmemiş olmasıdır. Java'da iç içe statik sınıfın örneğini oluşturmak için herhangi bir Outer sınıfı örneğine de ihtiyacınız yoktur.

1) Özel dahil dış sınıfın statik veri üyeleri öğesine erişebilir.
2) Statik yuvalanmış sınıf, statik olmayan (örnek) veri üyesi veya yöntem öğesine erişemez.

public class NestedStaticExample {
    public static void main(String args[]){  
        StaticNested nested = new StaticNested();
        nested.name();
    }  
    //static nested class in Java
    private static class StaticNested{
        public void name(){
            System.out.println("static nested class example in Java");
        }
    }
}

Ref: Örnek olarak Java'da iç sınıf ve iç içe Statik Sınıf

6
roottraveller

Bir sınıfın içindeki statik üye sınıfını bildirdiğimizde, üst düzey iç içe sınıf veya statik iç içe sınıf olarak bilinir. Aşağıdaki gibi gösterilebilir: 

class Test{
    private static int x = 1;
        static class A{
        private static int y = 2;
        public static int getZ(){
            return B.z+x;
        }
    }
    static class B{
        private static int z = 3;
        public static int getY(){
            return A.y;
        }
    }
}

class TestDemo{
     public static void main(String[] args){
        Test t = new Test();
        System.out.println(Test.A.getZ());
        System.out.println(Test.B.getY());
    }
}

Bir sınıfın içinde statik olmayan üye sınıfını ilan ettiğimizde iç sınıf olarak bilinir. İç sınıf aşağıdaki gibi gösterilebilir: 

    class Test{
        private int i = 10;
        class A{
            private int i =20;
            void display(){
            int i = 30;
            System.out.println(i);
            System.out.println(this.i);
            System.out.println(Test.this.i);
        }
    }
}
5
Pankti

Buradaki insanların Poster'e dikkat etmesi gerektiğini düşünüyorum: Statik Yuva Sınıfı sadece ilk iç sınıf ..__ Örneğin:

 public static class A {} //ERROR

 public class A {
     public class B {
         public static class C {} //ERROR
     }
 }

 public class A {
     public static class B {} //COMPILE !!!

 }

Dolayısıyla, özetle, statik sınıf, hangi sınıfı içerdiğini bağlı değildir. Yani normal sınıfta olamazlar. (çünkü normal sınıf bir örneğe ihtiyaç duyar).

5
hqt

Aşağıdaki bir static nested class ve inner class örneğidir:

OuterClass.Java

public class OuterClass {
     private String someVariable = "Non Static";

     private static String anotherStaticVariable = "Static";  

     OuterClass(){

     }

     //Nested classes are static
     static class StaticNestedClass{
        private static String privateStaticNestedClassVariable = "Private Static Nested Class Variable"; 

        //can access private variables declared in the outer class
        public static void getPrivateVariableofOuterClass(){
            System.out.println(anotherStaticVariable);
        }
     }

     //non static
     class InnerClass{

         //can access private variables of outer class
         public String getPrivateNonStaticVariableOfOuterClass(){
             return someVariable;
         }
     }

     public static void accessStaticClass(){
         //can access any variable declared inside the Static Nested Class 
         //even if it private
         String var = OuterClass.StaticNestedClass.privateStaticNestedClassVariable; 
         System.out.println(var);
     }

}

OuterClassTest:

public class OuterClassTest {
    public static void main(String[] args) {

        //access the Static Nested Class
        OuterClass.StaticNestedClass.getPrivateVariableofOuterClass();

        //test the private variable declared inside the static nested class
        OuterClass.accessStaticClass();
        /*
         * Inner Class Test
         * */

        //Declaration

        //first instantiate the outer class
        OuterClass outerClass = new OuterClass();

        //then instantiate the inner class
        OuterClass.InnerClass innerClassExample =  outerClass. new InnerClass();

        //test the non static private variable
        System.out.println(innerClassExample.getPrivateNonStaticVariableOfOuterClass()); 

    }

}
3
Pritam Banerjee

Bir diyagram

enter image description here

static nested ve non-static nested sınıfları arasındaki fark

  • Statik iç içe geçmiş sınıflar, çevreleyen sınıfın diğer üyelerine (statik olmayan değişkenler ve yöntemler) doğrudan erişemez çünkü statik olduğu için, çevreleyen sınıfının statik olmayan üyelerine bir nesne üzerinden erişmelidir. Diğer bir deyişle, etrafındaki sınıfın statik olmayan üyelerine doğrudan başvuramaz. Bu kısıtlama nedeniyle, statik iç içe sınıflar nadiren kullanılır.
  • Statik olmayan iç içe sınıflar (iç sınıflar), dış sınıfının tüm üyelerine (statik ve statik olmayan değişkenler ve özel olanlar da dahil olmak üzere) erişebilir ve bunlara doğrudan dıştaki diğer statik olmayan üyeler gibi başvurabilirler. sınıf yapmak.

Devamını oku burada

1
yoAlex5

Yukarıdaki cevapların hiçbirinin uygulama tasarımı açısından iç içe geçmiş bir sınıfla statik iç içe geçmiş bir sınıf arasındaki farkı size gerçek bir örnek vermediğini düşünüyorum. Statik iç içe sınıf ile iç sınıf arasındaki temel fark, dış sınıf örnek alanına erişme yeteneğidir.

Aşağıdaki iki örneğe bir göz atalım.

Statik yuva sınıfı: Statik yuvalanmış sınıfları kullanmanın iyi bir örneği oluşturucu desenidir ( https://dzone.com/articles/design-patterns-the-builder-pattern ).

BankAccount için, çoğunlukla çünkü statik bir iç içe sınıf kullanıyoruz.

  1. Dış sınıftan önce statik yuva sınıfı örneği oluşturulabilir.

  2. Oluşturucu düzeninde, oluşturucu, BankAccount'u oluşturmak için kullanılan yardımcı bir sınıftır.

  3. BankAccount.Builder yalnızca BankAccount ile ilişkilidir. BankAccount.Builder ile ilgili başka bir sınıf yok. bu yüzden isim kurallarını kullanmadan onları birlikte organize etmek daha iyidir.
public class BankAccount {

    private long accountNumber;
    private String owner;
    ...

    public static class Builder {

    private long accountNumber;
    private String owner;
    ...

    static public Builder(long accountNumber) {
        this.accountNumber = accountNumber;
    }

    public Builder withOwner(String owner){
        this.owner = owner;
        return this; 
    }

    ...
    public BankAccount build(){
            BankAccount account = new BankAccount(); 
            account.accountNumber = this.accountNumber;
            account.owner = this.owner;
            ...
            return account;
        }
    }
}

İç sınıf: İç sınıfların ortak kullanımı, bir olay işleyiciyi tanımlamaktır. https://docs.Oracle.com/javase/tutorial/uiswing/events/generalrules.html

MyClass için iç sınıfı kullanıyoruz, çünkü:

  1. İç sınıf MyAdapter'ın dış sınıf üyesine erişmesi gerekir.

  2. Örnekte, MyAdapter yalnızca MyClass ile ilişkilidir. MyAdapter ile ilgili başka hiçbir sınıf yok. bu yüzden bir isim anlaşması kullanmadan onları birlikte organize etmek daha iyidir

public class MyClass extends Applet {
    ...
        someObject.addMouseListener(new MyAdapter());
    ...
    class MyAdapter extends MouseAdapter {
        public void mouseClicked(MouseEvent e) {
            ...// Event listener implementation goes here...
            ...// change some outer class instance property depend on the event
        }
    }
}
1
Leogao

Java programlama dili, başka bir sınıf içinde bir sınıf tanımlamanıza izin verir. Böyle bir sınıfa yuvalanmış bir sınıf denir ve burada gösterilmektedir:

class OuterClass {
...
class NestedClass {
    ...
    }
}

İç içe sınıflar iki kategoriye ayrılır: statik ve statik olmayan. Statik olarak bildirilen iç içe sınıflar, statik iç içe sınıflar olarak adlandırılır. Statik olmayan iç içe sınıflar iç sınıflar olarak adlandırılır .. .. Aklımızda tutmamız gereken şeylerden biri, statik olmayan iç içe sınıfların (iç sınıflar), özel olarak ilan edilmiş olsalar bile, çevreleyen sınıfın diğer üyelerine erişimidir. Statik iç içe sınıflar, statik olmaları durumunda yalnızca çevre sınıfının diğer üyelerine erişebilir. Dış sınıfın statik olmayan üyelerine erişemez .. __ Sınıf yöntemleri ve değişkenlerinde olduğu gibi, statik iç içe sınıf, dış sınıfı ile ilişkilendirilir. Örneğin, statik iç içe sınıf için bir nesne oluşturmak için bu sözdizimini kullanın:

OuterClass.StaticNestedClass nestedObject =
 new OuterClass.StaticNestedClass(); 

Bir iç sınıfı örneklemek için, önce dış sınıfı örneklemelisiniz. Daha sonra, bu sözdizimiyle dış nesnenin içindeki iç nesneyi oluşturun:

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

Neden iç içe sınıfları kullanıyoruz

  1. Bu, yalnızca bir yerde kullanılan sınıfları mantıksal olarak gruplandırmanın bir yoludur.
  2. Kapsülleme artar.
  3. Daha okunaklı ve bakım yapılabilir kodlara yol açabilir.

Kaynak: Java ™ Öğreticileri - İç İçe Sınıflar

0
Mithun Debnath

Öncelikle Statik sınıf diye bir sınıf yoktur. İç sınıfla (Statik Sınıf olarak adlandırılır) Statik değiştirici kullanımı, Dış Sınıfın statik bir üyesi olduğunu söyler; Dış sınıf örneği. (Aslen statik olanın faydasıdır.) 

Nested sınıfını ve normal Inner sınıfını kullanma arasındaki fark:

OuterClass.InnerClass inner = new OuterClass().new InnerClass();

Önce Outerclass'ı başlatabiliriz sonra da Inner'a erişebiliriz.

Ancak, Sınıf Yuvalanmışsa, sözdizimi şöyledir:

OuterClass.InnerClass inner = new OuterClass.InnerClass();

Statik sözdizimini, statik anahtar kelimenin normal uygulaması olarak kullanır.

0
Sohi