"Enter"a basıp içeriğe geçin

Java’da kalıtım (Inheritance)

Java’da kalıtım, mevcut class’lara (sınıflara) ek işlevler eklemek için kullanılır. Kalıtım kullanarak, var olan class’lara ek özellikler ekleyerek onları genişletebiliriz. Kalıtım kullanarak, class’larımızı yeniden kullanabilir hala getirebilir, denetimlerimizi testlerimizi tekrar tekrar her seferinde yeniden yapmadan, aynı kodları tekrar tekrar compile (derleme) etmeden yazılım geliştirebiliriz.

Java’da kalıtım, aşağıdaki örnekte göreceğiniz gibi extend keyword’u kullanılarak uygulanır.

class A {
    int i;
 
    void metodBir() {
        System.out.println("metodBir");
    }
}
 
class B extends A {
    int j;
 
    void metodIki() {
        System.out.println("metodIki");
    }
}

A class’ının iki adet üyesi vardır. Bunlar “i” ve “metodBir()” dir. B class’ında da iki adet üye vardır. Bunlar “j” ve “metodIki()” dir. Ancak B class’ı, A class’ından extend edilmiştir. Kalıtım işlemi sayesinde aslında B class’ının 4 adet üyesi vardır. Bunlar “i“, “metodBir()“, “j” ve “metodIki()” üyeleridir. Yani B class’ı kalıtım ile A class’ının da üyelerini kendi içinde barındırır hale gelmiştir.

Burada A class’ı “super class” olarak, B class’ı “sub class” olarak adlandırılır. Ufak bir analiz yaparsak; A class’ına, B class’ını kullanarak yeni özellikler ekledik ve A class’ını genişletmiş olduk. Ayrıca B class’ının özelliklerini yeniden A class’ı içinde yazmadan B class’ını tekrar kullanmış olduk.

Java’da kalıtım yaparken unutulmaması gereken noktalar:

Bu kısımda java’da kalıtım ile ilgili bazı noktaları ele alacağız.

Super class’ların Constructor’ları (Kurucu fonksiyonlar), SIB (Static Initializetion Blokları) ve IIB (Instance Initialization Blokları) sub class’lara (alt sınıflara) miras olarak aktarılmazlar, ancak sub class oluşturulurken, super class içindeki constructorlari SIB ve IIB ler yinede çalıştırılırlar. Örneğin:

class A {
    int i;
 
    static {
        System.out.println("A Class'ına ait SIB");
    }
 
    static {
        System.out.println("A Class'ına ait IIB");
    }
 
    A() {
        System.out.println("A Class'ına ait Constructor");
    }
}
 
class B extends A {
    int j;
}
 
class MainClass {
 
    public static void main(String[] args) {
        B b = new B();
    }
}

Yukarıdaki programda B class’ı A Class’ından extend edildi. MainClass’da ise B class’ından bir instance (örnek) oluşturuluyor. Bu işlem sırasında SIB, IIB ve constructor’ın çalıştırıldığı izlenebilir. Yukarıdaki proramın çıktısı şu şekilde olur:

A Class'ına ait SIB
A Class'ına ait IIB
A Class'ına ait Constructor
  • Aşağıdaki programı derleyelim,
class A {
    int i;
 
    A(int i) {
        System.out.println("A Class'ına ait Constructor");
    }
}
 
class B extends A {
    int j;
}

Derleme sırasında  Implicit default constructor A() is undefined for Class A  hatası ile karşılaşacaksınız. Bu hatanın sebebini anlatmak biraz karışık olsa da, sizlerin anlayacağını düşünüyorum. Compiler (derleyici) B class’ı içine constructor yazmanız konusunda sizi zorluyor. Çünkü B class’ında tanımlı bir constructor yok. Ancak Java’da kurucu fonksiyon (Constructor) yazımı ile ilgili basit kurallar yazımda anlatıldığı gibi; bir class içinerisine constructor yazılmaz ise compiler (derleyici) parametresiz olan varsayılan constructor’ı derleme esnasında oluşturur (her hangi bir constructor yazılmış ise derleyici müdahale etmez).  Kalıtım yapılmış bir class ise, ilk satırında super class’ın varsayılan constructor’ı otomatik olarak çağırılır. Ancak A class’ının varsayılan (parametresiz) constructor’ı olmadığı için sorun yaşanır. Bu hatayı düzeltmek için birden çok yol vardır. A class’ı içerisine  A(){ }  şeklinde varsayılan cunstructor oluşturulabilir. Diğer bir yol ise, B class’ı içerisine constructor yazmak. Aşğıdaki kod incelenebilir. Bu kod derlendiğinde hata ile karşılaşılmaz.

class A {
    int i;
 
    A(int i) {
        System.out.println("A Class'ına ait Constructor");
    }
}
 
class B extends A {
    int j;
 
    public B() {
        super(10);     //super komutu ile A class'ının constructor'ı çağırılıyor.
        System.out.println("B Class'ına ait Constructor");
    }
}
  • Varsayılan olarak bütün class’lar java.lang.Object class’ından extend edilmiştir. Compiler derleme sırasında otomatik olarak extend işlemini gerçekleştirir.
class A {
     //diğer satırlar
}

yukarıdaki kodu compiler otomatik olarak aşağıdaki şekilde derler.

class A extends Object{
     //diğer satırlar
}
  • Hiç bir class kendisi ile extend edilemez. Compile time hatası ile karşılaşılır.
class A extends A {
     //compile time hatası
}
  • super class’ın constructor’ını, sub class’dan super() komutu ile çağırabiliriz. Aynı class içerisindeki diğer constractorları this() deyimi ileçağırabiliriz. Ancak sub class constructor’unu super class içersinden çağıramayız.
class A {
    A() {
        //B();      super class constructor içinden sub class constructor'ı çağırılamaz.
        System.out.println("Class A Constructor");
    }
}
 
class B extends A {
    B() {
        super();        // bu deyim ile super class constructor'ı çağırılıyor.
        System.out.println("Class B Constructor");
    }
}

private, default, protected ve public keywordlerinin java’da kalıtıma etkileri:

private: private olarak tanımlanmış member’lar (üyeler), sub class’lara devredilemezler.

default: default olarak tanımlanmış member’lar, aynı paket (package) içersinde bulunan sub class’lara devredilebilirler.

protected: protected olarak tanımlanmış member’lar, bütün sub class’lara devredilebilirler. Ancak buluğunduğu paket içinde kullanılabilir.

public: public olarak tanımlanmış member’lar, bütün sub class’lara devredilebilirler.

Aşağıdaki örnek ile bu konuyu daha da pekiştirebiliriz.

package com1;
 
public class A {
    private int i;
    int j;
    protected int k;
    public int m;
}
 
class B extends A {
    void classBMetodu() {
        //System.out.println(i);        //Private member devredilemez.
        System.out.println(j);          //Default member aynı paket içinde olduğu için devredilebilir.
        System.out.println(k);          //protected member butun sub class'lara devredilebilir.
        System.out.println(m);          //public member bütün sub class'lara devredilebilir.
    }
}
 
class C extends B {
    void methodOfClassC() {
        System.out.println(j);          //Default member aynı paket içinde olduğu için devredilebilir.
        System.out.println(k);          //protected member sub class'lara devredilebilir.
        System.out.println(m);          //public member bütün sub class'lara devredilebilir.
 
        B b = new B();
        System.out.println(b.j);        //Default member aynı paket içinde olduğu için kullanılabilir.
        System.out.println(b.k);        //protected member paket içerisinde olduğu için kullanılabilir.
        System.out.println(b.m);        //public member her yerde kullanılabilir.
    }
}
package com2;
        import com1.A;
 
public class D extends A {
    void methodOfClassD() {
        //System.out.println(j);        //Default member'lar paket dışına devredilemezler
        System.out.println(k);          //protected member sub class'lara devredilebilir.
        System.out.println(m);          //public member bütün sub class'lara devredilebilir.
 
        A a = new A();
        //System.out.println(a.i);      //private member class dışında kullanılamaz.
        //System.out.println(a.j);      //Default member'lar paket dışında kullanılamaz.
        //System.out.println(a.k);      //Protected member paket dışında kullanılamaz.
        System.out.println(a.m);        //public member her yerde kullanılabilir.
    }
}
 
class E extends D {
    void methodOfClassE() {
        System.out.println(k);          //Protected member istenilen sub class'a devredilebilir.
        System.out.println(m);          //public member her zaman devredilebilir.
 
        D d = new D();
        //System.out.println(d.k);      //Protected member paket dışında kullanılamaz.
        System.out.println(d.m);        //public member her yerde kullanılabilir.
    }
}

Java’da kalıtım (inheritance) türleri:

  • Single Inheritance: Bir class yanlızca bir class’dan extend olur.
  • Multilevel Inheritance: Bir class, başka bir class’dan, bu class’da diğer bir class’dan extend olur. Bı işlem zincir şeklinde devam edebilir.
  • Hierarchical Inheritance: Bir class, bir çok class’ı extend eder. Yani bir super class ve birden çok sub class olabilir.
  • Hybrid Inheritance: Bu tür yukarıda saydığım türlerin karışımıdır. Birden çok türde Inharitance yapısını bünyesinde barındırır.
  • Multiple Inheritance: Bir sınıf, birden fazla sınıftan extend olur. Multiple Inheritance JAVA tarafından desteklenmez. Multiple Inheritance’ı anlamak için aşağıdaki örneği inceleyelim.
class A {
    void metodBir() {
        System.out.println("A class'ının metodu");
    }
}
 
class B {
    void metodBir() {
        System.out.println("B class'ının metodu");
    }
}
 
class C extends A, B(Eğer desteklanirse){
        //C class'ı A ve B class'larından extend oluyor.
        //Javanın bu tür kalıtım desteği yok. Javada hata alınır.
}

C class’ı A class içinde tanımlanmış olan metodBir() ve B clasında tanımlı olan metodBir() metodları C class’ına aktarılır.

2 Yorum

  1. […] Kalıtım ile ilgili makalede anlattığım gibi, java da çoklu kalıtım yani “Multi Inheritance” yoktur. Bu sorunu ortadan kaldırmak için gömülü sınıfları kullanıyoruz. “Statik Gömülü Sınıf” hakkındaki bilgileri burada daha önceden vermiştim. Ortak konular olduğu için eğer okumadıysanız ilgili makaleyi buradan okuyabilirsiniz. Şimdi konumuza geçebiliriz. […]

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir