Abstract sınıflar ve Interface karşılaştırması (Java)

Abstract sınıflar ve Interface karşılaştırması (Java)

Herkese merhabalar, Bu yazıda sizlere Nesne Yönelimli programlama ile birlikte gelen Abstract class ve interface özellikleri ve aralarındaki farkları Java ile anlatmaya çalışacağım.

Başlayalım.

İlk olarak Abstraction Nedir Abstracton, bir sınıfın kendi iç özelliklerini dışarıdan saklayarak sadece dışarıya sağlaması beklenen komutların ve propertylerin sağlanması olayıdır. Yani bir işlem yapılır fakat kullanıcı sınıf, bu işlemin nasıl yapıldığını bilmez. Bu özelliğe Abstraction denir.
Interface ve abstract sınıflar, Abstraction özelliği için kullanılmaktadır.

İlk olarak aşağıdaki tabloda abstract sınıflar ve interface'ler arasında genel bir karşılaştırma yapalım.

Abstract Sınıf Interface
Abstract sınıftan extends ile kalıtım alınabilir . Interface ise implements ile sınıfa implemente edilir ve bu şekilde kalıtım alınır.
Bir sınıf yalnızca birtane abstract class extend edebilir. Bir sınıf birden fazla interface'ten kalıtım alabilir. Birden fazla interface implmente edilebilir..
Abstract sınıflar içerisine hem sanal metodlar hem normal metodlar tanımlanabilir. Interface içerisinde metodlar sadece sanal metod olarak tanımlanabilir. Metod body kısmı tanımlanmaz.
Abstract sınıflar hem diğer abstract sınıfları extend ederek, hemde diğer interface'leri implemente ederek çoklu kalıtım alabilir. Interface'ler sadece diğer inteface'leri implemente ederek çoklu kalıtım alabilir. Bu işlem extend kelimesi ile yapılır.
Abstract sınıflar, interface lerden kalıtım alabilir. Bunun için bir interface'i implemente etmesi gerekir.. Interface'ler ise abstract sınıfları extend edemezler, yani kalıtım alamazlar.
Abstract sınıflar içerisine tanımlanan elemanlar, abstraction için bütün erişim belirteçlerini alabilir. public, private, protected... Interface içerisinde tanımlanan elemanlar ise default olarak public tanımlıdır. Tanımlama esnasında herhangi bir erişim belirteci kullanılmaz..
Abstract sınıflar içerisine tanımlanan değerler final ve normal şekilde tanımlanabilir. Interface'ler içerisinde tanımlanan değişkenler default olarak final tanımlıdır.
Abstract sınıflar içerisine, final, final olmayan, static ve static olmayan tiplerde değişkenler tanımlanabilir. Interface içerisine sadece static ve final değişkenler tanımlanabilir.

Aşağıda bir abstract sınıf tanımlayalım ve bu sınıfta kullandığımız özellikleri inceleyelim.

İlk olarak örneğimizde kullanabilmek adına aşağıdaki abstract sınıf ve interface oluşturuluştur.

interface ikiTekerlek{
    int getWheelCount();
}

interface aracDavranislari{

}

abstract class Araclar implements aracDavranislari{
    abstract void calistir();
    void ureticiyiGetir(){ 
        System.out.println("Thecodeprogram"); 
    };
    
    final public int finalDegisken = 4;
    final public static double finalStaticDegisken = 33;
    static boolean staticDegisken = true;
    
    public int publicDegisken = 5;
    private int privateDegisken = 6;
    protected float protectedDegisken = 7;
}
Sonrasında yukarıda oluşturulan abstract sınıftan kalıtım alan başka bir sınıf oluşturulmuş olup, bu sınıf içerisinde deneme metodları yazılmıştır.

class Kamyon extends Araclar implements ikiTekerlek{
    
    @Override
    void calistir(){
        System.out.println("Truck sınıfı başlatıldı"); 
    }

    @Override
    public int getWheelCount() {
        int tekerlekSayisi = 2;
        return tekerlekSayisi;
    }
    
    public void herseyiYazdır(){
        ureticiyiGetir();
        calistir();
        
        System.out.println("tekerlek sayısı : " + getWheelCount());
        System.out.println("finalDegisken : " + finalDegisken);
        System.out.println("finalStaticDegisken : " + finalStaticDegisken);
        System.out.println("staticDegisken : " + staticDegisken);
        System.out.println("publicDegisken : " + publicDegisken);
        System.out.println("privateDegisken : " + "Private yazdırılamaz :))");
        System.out.println("protectedDegisken : " + protectedDegisken);
    }
}
Sonrasında bu sınıf main fonksiyonu içerisinde başlatılır ve bütün değişkenlerin yazdırılması istenir.

public class AbstractClassInterfaceKarsilastirma {
    public static void main(String[] args) {
        Kamyon kamyon = new Kamyon();
        kamyon.herseyiYazdır();
    }
}
Program çıktısı aşağıdaki gibi olacaktır:

Thecodeprogram
Truck sınıfı başlatıldı
tekerlek sayısı : 2
finalDegisken : 4
finalStaticDegisken : 33.0
staticDegisken : true
publicDegisken : 5
privateDegisken : Private yazdırılamaz :))
protectedDegisken : 7.0
Bu örnek programda aşağıdaki özelliklerden faydalanılmıştır :
  • Oluşturulan abstract sınıf başka bir sınıf tarafından extend edilebilmiştir. Bu sınıf aynı anda başka bir interface'i implemente edebilmiştir.
  • Abstract sınıf birde interface implemente etmiştir.
  • Abstract sınıf içerisinde hem sanal hemde normal metod tanımlanmıştır.
  • Abstract sınıf içerisine final, static ve bunların dışında değişken tipleri kullanılmıştır.
  • Çeşitli erişim belirteçleri kullanılmıştır.

Şimdi birde Interface ile ilgili bir örnek yapalım ve bahsettiğimiz özelliklerini kullanmaya çalışalım.

İlk önce oluşturacağımız sınıfta kullanmak üzere interface'ler ve bir tane abstract sınıf oluşturalım. Bu kod bloğunda bir interface'in başka bir interface'i extend ettiğini görebilmekteyiz.


abstract class Arac{
    abstract String getMarka();
    abstract String getModel();
}

interface AracSahip{
    String getSahip();
}

interface AracKimlik extends AracSahip {
    final static int koltukSayisi = 4;
    String getSasiNo();
}

interface AracIslemler{
    void calistir();
    void durdur();
}

Ardından yukarıda oluşturulan yapılardan kalıtım alacak ve o davranışları sergileyecek bir sınıf oluşturalım. Burada görüldüğü üzere çoklu interface implementasyon yapılmıştır.


class Murat124 extends Arac implements AracKimlik, AracIslemler{
    
    public int getkoltukSayisi(){ return koltukSayisi; }

    @Override
    public String getSasiNo(){return "33AASASDGSG41545A"; }
    
    @Override
    public String getSahip(){return "Burak Hamdi TUFAN"; }
    
    
    @Override
    public void calistir(){ System.out.println("Araba Çalıştırıldı"); }
    
    @Override
    public void durdur(){ System.out.println("Araba Durduruldu"); }

    @Override
    String getMarka(){return "Murat124"; }
    
    @Override
    String getModel(){return "1995"; }
    
    public void butunOzellikleriYazdır(){
        System.out.println( "Marka : " + getMarka() );
        System.out.println( "Model : " +  getModel() );
        System.out.println( "Sahibi : " +  getSahip() );
        System.out.println( "Sasi No : " +  getSasiNo() );
        System.out.println( "Koltuk Sayisi : " +  getkoltukSayisi() );
    }
}

Ve son olarak main fonksiyonumuzda bu sınıfımızı çağıralım.


public class AbstractClassInterfaceKarsilastirma {
    public static void main(String[] args) {
        //Kamyon kamyon = new Kamyon();
        //kamyon.herseyiYazdır();
        
        Murat124 murat124 = new Murat124();
        murat124.butunOzellikleriYazdır();
        murat124.calistir();
        murat124.durdur();
        
    }
}
Program çıktısı aşağıdaki gibi olacaktır.

Marka : Murat124
Model : 1995
Sahibi : Burak Hamdi TUFAN
Sasi No : 33AASASDGSG41545A
Koltuk Sayisi : 4
Araba Çalıştırıldı
Araba Durduruldu

Peki hangisini ne zaman kullanmalı

Programımızda eğer birden fazla sınıf aynı türden olacaksa ve ortak metodlar kullanacaksa, abstract sınıflar burada kullanışlı hale gelmektedir. Abstract sınıflar ile türetilen sınıflara hem ortak fonksiyonlar saylayabiliriz hemde abstract metodlar oluşturarak bu fonksiyonların overide edilmesini sağlayıp davranışlar kazandırabiliriz. Override edilen metodlar ilgili sınıflar içerisinde aynı metod ismi ile yazılarak metod içeriği ilgili sınıfa göre yazılır. Bu sayede aynı tür sınıflar oluştururken aynı kodları defalarca yazmak yerine bir defa yazarız ve diğer sınıflarda kullanırız.

Bir sınıfa, bir davranış kazandırılmak isteniyorsa interface'ler çok güzel bir seçenektir. Interface yapısı aracılığı ile bir sınıfın ne yapması isteniyorsa o metod veya property, implemente edilen sınıf içerisinde tanımlanmak zorundadır. Bu sayede ilgili sınıf o işlemi yapar ama bunu kendi iç implementasyonları ile yapar ve dışarıdan sınıflar nasıl yapıldığını bilmez. Abstraction özelliğinin canlı örneğidir.

Bu yazımızda buraya kadar.

Örnek kaynak kodlara aşağıdaki link aracılığı ile Github üzerinden ulaşabilirsiniz... https://github.com/thecodeprogram/TheSingleFiles/blob/master/AbstractClassInterfaceKarsilastirma.java

Burak Hamdi TUFAN


Tags


Share this Post

Send with Whatsapp

Post a Comment

Success! Your comment sent to post. It will be showed after confirmation.
Error! There was an error sending your comment.

Comments

  • There is no comment. Be the owner of first comment...