Java Dersleri 8 – İç, Gömülü ve İsimsiz Sınıflar (Inner, Nested and Anonymous Classes)

Bu dersimizde Java’nın gömülü sınıf yapısını öğreneceğiz. Java programlama dili kullanıcıya bir sınıf içerisinde başka bir sınıf tanımlama olanağı sağlar. Bu tür sınıflara Gömülü Sınıf (Nested Class) adı verilir. Gömülü sınıflar statik ve statik olmayan gömülü sınıflar olmak üzere ikiye ayrılırlar. Statik olmayan gömülü sınıflara İç Sınıf(Inner Class) adı verilir. Gömülü sınıfların üç temel faydası vardır. Bunlar :

  1. Sınıfların Mantıksal Gruplanması : Ortak iş yapan sınıfların bir arada bulunmasını sağlayarak daha sağlıklı API’ler oluşturmanızı sağlar
  2. Daha İyi Kapsülleme : Sınıf değişkenlerinin private kalmasını sağlayarak daha iyi kapsülleme sağlar
  3. Kod Okunabilirliği : Üst seviye sınıflar altında iş gören gömülü sınıflar kod okunabilirliğini arttırır.

Gömülü sınıf hiyerarşisi aynı zamanda arayüzler için de geçerlidir. Yani arayüzlerde birbirleri içerisinde tanımlanabilirler. Java JDK içerisinde gömülü sınıf kullanımına örnek olabilircek çok sayıda sınıf ve arayüz vardır. Bunlardan bir tanesini inceleyelim :

//üst seviye arayüz tanımı
public interface Map<K ,V> {
int size();
boolean isEmpty();
boolean containsKey(Object key);
boolean containsValue(Object value);
V get(Object key);
V put(K key, V value);
V remove(Object key);
void putAll(Map<? extends K, ? extends V>m);
void clear();
Set<K> keySet();
Collection<V> values();

//gömülü arayüze referans var
Set<Map.Entry<K, V>>; entrySet();

//gömülü arayüz tanımı
interface Entry<K ,V>
{
K getKey();
V getValue();
V setValue(V value);
boolean equals(Object o);
int hashCode();
}

boolean equals(Object o);
int hashCode();
}

Örnekte görüldüğü üzere Map arayüzünün altında Entry gömülü arayüzü tanımlanmış ve

//gömülü arayüze referans var
Set<Map.Entry<K, V>>entrySet();

metod imzasında gömülü arayüz kullanılmıştır. Bu kullanımdan yola çıkarak gömülü arayüz/sınıf tanımlarına nasıl ulaşabiliriz onu görelim. Burada yine statik gömülü sınıflar ve iç sınıflar arasında ayrım yapmalıyız. Statik gömülü sınıftan bir nesne oluşturmak istiyorsak :

ÜstSeviyeSınıf.StatikGömülüSınıf  s  = new ÜstSeviyeSınıf.StatikGömülüSınıf();

Statik gömülü sınıftan bir nesne oluşturmak için üst seviye sınıftan nesne oluşturmamıza gerek yoktur. Oysa ki iç sınıflar üst seviye sınıf olmadan oluşturulamazlar. Yani statik olmayan iç sınıfların varlığı üst seviye sınıfa bağlıdır. Herhangi bir iç sınıfdan nesne oluşturmak için ise :

ÜstSeviyeSınıf s = new ÜstSeviyeSınıf();
ÜstSeviyeSınıf.İçSınıf i = s.new İçSınıf();

Burada en çok dikkat etmemiz gereken kullanım s.new kullanımıdır.

Sınıf tanımı veya herhangi bir metod tanımı içinde isim vermeden yeni bir sınıf tanımı yapılabilir. Bu şekilde tanımlanan sınıflara isimsiz (anonymous) sınıflar denir.  İsimsiz sınıflar sadece tanımlandıkları yerde kullanılırlar.  En klasik kullanım alanları …Listener (ActionListener,MouseMotionListener vs) gerçeklemeleridir. Örneğin NetBeans tarafından düğme kontrolü için üretilen kodları inceleyelim :


jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});

Burada addActionLisener metodu parametre olarak ActionListener arayüzünü gerçekleyen bir nesne alır.  Bu nesne isimsiz olarak tanımlanıp ActionListener’da gerçeklenmesi gereken actionPerformed metodunu içerir. Görüldüğü gibi sadece sınıf tanımı yapılıp sınıfa herhangi bir isim verilmemiştir.  İsimsiz sınıf tanımlama sentaksı


new Sınıfİsmi/Arayüzİsmi () {}

şeklindedir. Eğer Sınıfİsmi verilmişse isimsiz sınıf bu sınıftan türer. Eğer Arayüzİsmi verilmişse isimsiz sınıf bu arayüzü gerçekler.