JAVA – Nested (Gömülü), Inner (Dahili), Local (Lokal) ve Anonymous (İsimsiz) sınıflar

JAVA – Nested (Gömülü), Inner (Dahili), Local (Lokal) ve Anonymous (İsimsiz) sınıflar

1 Ekim 2012 0 Yazar: Cem Kefeli

Java’da her şey sınıflardan oluşuyor demiştim.Sınıf tanımlamak kolay, sınıfların örneklerinden nesneler oluşturmak da kolay. Fakat işin özüne inecek ulursanız bazı trig’ler ile karşılaşmaya başlayacaksınız. Bu yazının başlığında geçen sınıf türleri de işte bu tirg’lere birer örnek. Olmasalar ne olurdu? Çok net bir şekilde, İsimsiz Sınıflar hariç hiç bir şey olmazdı diyebilirim aslında. Dedim ya birkaç trig. Dilin esnekliği ve sunduğu olanaklar ile ilgili tamamen. Zaten bu kavramlar Java’ya özgü birşey de değiller. OOP dilleri için genel bir konsepttir. Türkçe’ye çevrilmiş halleri ise bana hep oldukça karışık gelir, ama yazı boyunca aşağıdaki anlamları ifade ettiğini bilerek okuyunuz lütfen, her ne kadar ben hep Türkçe isimleri kullanacak olsam da;

Nested Classes <–> Gömülü (İç içe geçmiş) sınıflar

Inner Classes <–> Dahili sınıflar

“Peki işe yararlar?” sorusuna gelirsek, Gömülü Sınıflar benzer görevi yapan sınfları daha okunaklı ve anlamlı bir şekilde kullanılabilir hale getirmek için uygundurlar mesela. ‘Biz bu işi zaten paketler (packages) ile yapmıyor muyduk?’ derseniz hiç bir şey diyemem, çünkü aynen öyle. Dahili Sınıf dediğimiz ise Gömülü Sınıfın bir türüdür. Statik olarak tanımlanmayan Gömülü Sınıfa, Dahili Sınıf denir. Statik olarak tanımlanan Gömülü Sınıflara ise Statik Gömülü Sınıflar denir. Yani aslında Gömülü Sınıf dedigimiz şey yalnızca özel bir isimlendirmedir. Çorba oldu değil mi? Yok yok çok karışık degil, örnek yapalim…

Nested Classes example

class HerhangiBirSinif {
    ...
    class GomuluSinif {
        ...
    }
}
class HerhangiBirSinif {
    class DahiliSinif {
        void Yaziyaz(){
            System.out.println("HerhangiBirSinif.DahiliSinif");
        }
    }
    static class StatikGomuluSinif {
        void Yaziyaz(){
            System.out.println("HerhangiBirSinif.StatikGomuluSinif");
        }        
    }
}

Fakat her kadar ‘Dahili Sınıf ve Statik Gömülü Sınıf aslında Gömülü Sınıfların türleridir.’ desek de bu türlerden oluşturulan nesne örneklerinin oluşturulma şekillleri farklıdır. Statik Gömülü Sınıflardan nesne örneği oluştururken önce kendilerini çevreleyen sınıfların nesne örneği oluşturulmaz (Satır-3). Fakat Dahili sınıfların nesne örneklerini oluştururken mutlaka ve mutlaka ilk önce kendilerini çevreleyen nesnelerin birer nesne örneğinin oluşturulması gereklidir (Satır-6).

Nested Classes example

public class Main {
    public static void main(String[] args) {
        HerhangiBirSinif.StatikGomuluSinif Statik_Gomulu_Sinif = new HerhangiBirSinif.StatikGomuluSinif();
        Statik_Gomulu_Sinif.Yaziyaz();        
        
        HerhangiBirSinif.DahiliSinif DahiliSinif = new HerhangiBirSinif().new DahiliSinif();
        DahiliSinif.Yaziyaz();
    }
}
HerhangiBirSinif.StatikGomuluSinif
HerhangiBirSinif.DahiliSinif

Bu örneklerden sonra artık konuyu dallı budaklı hale getirebiliriz, temeli attık diye düsünüyorum. İlk başta bahsetmemiştim ama bir de Yerel Sınıf kavramı var. Aslında tüm Yerel Sınıflar birer Dahili Sınıftır diyebiliriz tanım olarak. Dahili Sınıflardan farki ise Yerel Sınıflari çevreleyen başka sınıflar yoktur ve yalnızca tanımlı bulundukları kod bloklari, yani örneğin ‘{‘ ile baslayıp ‘}’ ile biten parçalar, için kullanılabilirler.

Local Class example  

public class Main {
    public static void main(String[] args) {
        class LokalSinif {
            void Yaziyaz(){
                System.out.println("Main.LokalSinif");
            }
        }                        
        new LokalSinif().Yaziyaz();

        {
            class EnLokalSinif {
                void Yaziyaz(){
                    System.out.println("Main.LokalSinif");
                }
            }  
            new EnLokalSinif().Yaziyaz();
        }        
        //new EnLokalSinif().Yaziyaz();
    }
}
Main.EnLokalSinif
Main.LokalSinif

Bir de İsimsiz (Anonymous) Sınıf kavramına bakalım. İsimsiz Sınıflar genellikle Action Listener’lar ile kullanılıyor. C#’daki Delegate mantığı ile aynı görevi üstleniyor. Aşağıdaki örnekte 7-11 numaralı satırlar arası İsimsiz Sınıfı oluşturuyor.

Anonymous Class example 

class HerhangiBirSinif {
    interface YaziIsleri {
        public String Yaz();
    }
    
    public YaziIsleri Yaz(final String Metin) {
        return new YaziIsleri() {
            public String Yaz() {
                return Metin;
            }
        };
    }
}
public class Main {
    public static void main(String[] args) {
        HerhangiBirSinif Herhangi_Bir_Sinif = new HerhangiBirSinif();
        String Yaz = Herhangi_Bir_Sinif.Yaz("Bu bir yazar...").Yaz();
        System.out.println(Yaz);
    }
}
Bu bir yazar...