İleri Programlama Dersi 6. Ünite Özet

Java’da Soyut Sınıflar ve Arayüzler

Giriş

Bu ünitede, soyut sınıf ve arayüz kavramları üzerinde duracağız. Ünitenin içeriğinde de görüleceği gibi bu iki başlığın aynı ünitede işlenmesinin sebebi kavramların birbirine benzer işlevleri olmasıdır. Bu kavramlar tanıtılırken birbirleri ile benzerlik ve farklılıkları da ortaya konulmuş olacaktır. Bu üniteye kadar sınıf ve nesne ilişkisini şu şekilde tarif ettik. Nesne, basit anlamda bir sınıfın gerçek hayattaki bir örneğidir. İnsan isimli bir sınıf tanımlandığında etrafımızdaki bireylerin onun bir örneği olduğunu söyleyebilmekteyiz. Ancak, nesneye yönelik programlamada her bir sınıfın bir örneği olmayabilir ve dolayısıyla o sınıf türünde nesneler oluşturamayabiliriz. Ana hatlarıyla soyut sınıf kavramı bu duruma işaret etmektedir. Herhangi bir sınıf, soyut olarak tanımlandığında o sınıf türünde nesne oluşturulabilmesi söz konusu olmayacaktır. Soyut sınıflar daha çok ilgili alt sınıflara ait detayların tanımlanması amacıyla kullanılırlar. Dolayısıyla soyut sınıflar, içeriğinde birtakım özelliklerin ve metotların tanımlanabildiği fakat kendi türünde nesnelerin yaratılamadığı sınıflardır. Ünitenin devamında bahsedeceğimiz bir diğer kavram da arayüz kavramıdır. Arayüz, bir sınıfta olması gereken metotları tanımlamaya yarayan bir yapıdır; fakat kesinlikle bir sınıf değildir. Amacı daha çok bir işlemin gerçekleşmesi için hangi metotların var olması gerektiğini belirlemektir. Arayüzlerin bu metotların içeriklerini tanımlamak gibi bir görevi yoktur. Bir arayüz, daha sonra herhangi bir sınıf tarafından uygulandığında bu metotların içerikleri ilgili sınıf tarafından tanımlanacaktır. Örneğin büyüklükleri karşılaştırma amacıyla bir arayüz tanımlandığında bunun farklı sınıflar üzerindeki uygulamaları da farklı olacaktır. Bu arayüzü uygulayan bir sınıf tarihlerin birbiriyle karşılaştırılmasını yaparken bir başka sınıf miktarların birbiriyle karşılaştırmasını yapabilir. Arayüz içerisinde sadece bu metodun ismi, hangi parametreleri alacağı ve ilgili metodun hangi tipte değer döndüreceği gibi bilgiler yer alacaktır. Java standart kütüphanesi içerisinde de programcıların uygulayabilecekleri bir takım hazır arayüzler bulunmaktadır.

Soyut Sınıflar

Soyut sınıf, giriş bölümünde de bahsedildiği gibi temel olarak kendisi türünde bir nesne oluşturulamayacak olan bir sınıftır. Nesneye yönelik programlamada sınıflar arasındaki kalıtım ilişkileri bir hiyerarşi şeklinde ifade edilebilir. Önceki ünitelerde bir sınıftan kalıtım yoluyla yeni bir sınıf türetildiğinde bu yeni sınıfın alt sınıf ve mevcut sınıfın üst sınıf olarak adlandırıldığından bahsetmiştik. Bu hiyerarşinin en üzerinde yer alan üst sınıflar kimi zaman sadece alt sınıflara ait işlemlerin tanımlanması açısından kullanılabilir. Böyle bir durumda bu üst sınıfın türünden nesne oluşturulması düşünülmemekte ve bunu ifade etmek için de bu sınıfın soyut olarak tanımlanması mümkün olmaktadır. Soyut sınıflarda bazı metotların içeriği tanımlamış fakat bazılarının içeriğinin tanımlanması ilgili alt sınıflara bırakılmıştır. Soyut sınıf, Java programlama dilinde abstract anahtar kelimesi ile tanımlanmaktadır. Aşağıda, soyut sınıf kullanımına temel bir örnek olarak Sekil isimli Java sınıfı verilmiştir. Sekil sınıfı tanımlanırken abstract anahtar kelimesinin kullanıldığını görmekteyiz. Bu sınıf, alanHesapla ve alanGoster isimli iki adet metoda sahiptir. Örneği dikkatle incelediğimiz zaman alanHesapla metodunun başında da abstract anahtar kelimesinin bulunduğunu gözleyebiliriz. Buna karşın alanGoster metodunun içerisinde böyle bir anahtar kelime bulunmamaktadır. Bir metodun önünde abstract anahtar kelimesinin bulunması o metodun içeriğinin belirlenmesinin kendisinden kalıtım yoluyla türeyecek olan yeni sınıflara bırakıldığı anlamına gelmektedir. Böyle metotlar, soyut metot olarak adlandırılmaktadır. Sınıf içerisinde yer alan bir diğer metot olan alanGoster ise içerik olarak tanımlanmış durumda olduğundan böyle bir anahtar kelimeye ihtiyaç bulunmamaktadır. Bu örnekte, Sekil sınıfından türeyecek olan Daire ve Dikdörtgen gibi sınıfların alan hesaplama yöntemlerinin farklı olacağı düşünülmüş ve bu sebeple ilgili metodun içeriğinin belirlenmesi bu sınıftan türetilecek diğer sınıflara bırakılmıştır.

/* Sekil.java */

public abstract class Sekil {

double alan; public abstract void alanHesapla();

public double alanGoster() {

return alan; }

}

Aşağıda, Sekil soyut sınıfından kalıtım yoluyla türetilen Daire ve Dikdörtgen sınıflarına ait Java kodları bulunmaktadır. Bu sınıflar içerisinde Sekil sınıfında yer alan soyut metotların içeriklerinin tanımlanması gerekmektedir. İlgili Java program kodları içerisinde bu metodun her iki sınıf için de farklı içeriklerle tanımlandığını görmekteyiz. Bir diğer metot olan alanGoster metodu ise kalıtım yoluyla Daire ve Dikdörtgen sınıflarına aktarılmaktadır. Dolayısıyla alanGoster metodunun herhangi bir yeni tanımlama yapılmadan bu sınıf türündeki nesneler tarafından çağrılabilmesi mümkün olacaktır.

/* Daire.java */

public class Daire extends Sekil{

double yaricap;

double piSayisi = 3.14; public void alanHesapla() {

alan = piSayisi * yaricap * yaricap;

}

public Daire(double yaricapDegeri) {

yaricap = yaricapDegeri;

}

}

/* Dikdortgen.java */

public class Dikdortgen extends Sekil{

double uzunluk, genislik;

public void alanHesapla() {

alan = uzunluk * genislik;

}

public Dikdortgen(double uzunlukDegeri, double genislikDegeri) {

uzunluk = uzunlukDegeri; genislik = genislikDegeri;

}

}

Bu sınıfların tamamının kullanımını bir uygulama içerisinde görebilmek için ise aşağıda Java kodlarını içeren SekilUygulamasi sınıfı kullanılmıştır. SekilUygulamasi sınıfı içerisinde Daire ve Dikdörtgen türündeki nesneler oluşturulmuş ve bu nesnelere ait metotlar çağrılmıştır. Sonuç olarak iki nesne için de alanHesapla ve alanGoster metotlarının çalıştırıldığını görmekteyiz. Bu metotlardan birisi soyut sınıf olan Sekil sınıfı içerisinde, diğeri de bu sınıftan kalıtım yoluyla türetilmiş olan Daire ve Dikdörtgen sınıfları içerisinde tanımlanmıştır

Aşağıda, soyut sınıf kavramı ile ilgili bir örnek daha bulunmaktadır. Bu örnekte soyut sınıf olarak tanımlanmış Kus isimli bir sınıf ve bu sınıftan kalıtım yoluyla türetilmiş olan Karga ve Serce sınıfları yer almaktadır.

/* Kus.java */

public abstract class Kus {

public abstract void turGoster();

}

/* Karga.java */

public class Karga extends Kus {

public void turGoster() {

System.out.println(“Tür = Karga”);

}

}

/* Serce.java */

public class Serce extends Kus {

public void turGoster() {

System.out.println(“Tür = Serçe”);

}

}

Bu sınıfların tamamının kullanımını bir uygulama içerisinde görebilmek için ise aşağıda KusUygulamasi isimli bir sınıf bulunmaktadır. KusUygulamasi sınıfı içerisinde Karga ve Serce türündeki nesneler oluşturulmuş ve bu nesnelere ait turGoster metodu çağrılmıştır. Bu metot, Kus sınıfı içerisinde bir soyut metot olarak tanımlanmıştır. Bu sebepten dolayı, Karga ve Serce sınıfları içerisinde bu soyut metodun içeriğinin tanımlandığını görmekteyiz. Ayrıca, KusUygulamasi sınıfı içerisindeki son iki satırın yorum satırı şeklinde olduğunu görmekteyiz. Bu satırlar soyut sınıf olan Kus sınıfı türünde bir nesne oluşturulamayacağını göstermek amaçlıdır. Eğer bu iki satır, yorum satırı olmaktan çıkarılıp aktif hâle getirilirse derleyici hatası ile karşılaşılacak ve program çalıştırılamayacaktır.

/* KusUygulamasi.java */

public class KusUygulamasi {

public static void main(String[] args)

{ Karga karga = new Karga();

Serce serce = new Serce();

karga.turGoster();

serce.turGoster();

// Kus kus = new Kus();

// kus.turGoster();

}

}

Arayüzler

Arayüz, bir sınıfta olması gereken metotların tanımlandığı bir yapıdır fakat kesinlikle bir sınıf değildir. Arayüzlerin amacı daha çok herhangi bir işlemin gerçekleşmesi için hangi metotların var olması gerektiğini belirlemektir. Bu metotların içerikleri ise arayüzleri uygulayan sınıflar tarafından oluşturulur. Arayüzler, Java programlama dilinde interface anahtar kelimesi ise tanımlanır. Örneğin aşağıda Bilgilendir isminde bir arayüz yer almaktadır. Bu arayüz içerisinde turGoster isminde bir metot tanımlanmıştır. Metodun içeriği belirli olmamakla birlikte herhangi bir değer döndürmeyeceği ve parametre almadığı görülmektedir.

/* Bilgilendir.java */

public interface Bilgilendir {

public void turGoster();

}

Aşağıda, Bilgilendir ismindeki arayüzü uygulayan iki adet sınıf ve bu sınıfları kullanan main metoduna sahip KusUygulamasi isimli bir sınıf yer almaktadır. İlgili sınıfları, soyut sınıf kavramına örnekler verirken de kullanmaktaydık. Bu örnek, aynı zamanda soyut sınıf kullanıldığı durumdaki işlevlerin arayüz kavramı ile nasıl gerçekleştirilebileceğinin anlaşılması açısından önemlidir

/* Serce.java */

public class Serce implements Bilgilendir {

public void turGoster() {

System.out.println("Tür = Serçe");

}

}

/* Karga.java */

public class Karga implements Bilgilendir {

public void turGoster() {

System.out.println(“Tür = Karga”);

}

}

/* KusUygulamasi.java */

public class KusUygulamasi {

public static void main(String[] args) {

Karga karga = new Karga();

Serce serce = new Serce();

karga.turGoster();

 serce.turGoster();

}

}

Aşağıda, arayüz kavramına bir örnek daha bulunmaktadır. Bu örnekte SekilHakkindaBilgi isminde bir arayüz ve bu arayüzü uygulayan sınıflar yer almaktadır. SekilHakkindaBilgi arayüzü, çevre ve alan değerlerinin gösterilmesi amacı taşıyan iki adet metoda sahiptir. Bu arayüzü uygulayan herhangi bir sınıfın çevre ve alan değerlerini hesaplayarak görüntülemesi gerekmektedir. Çevre ve alan değerlerinin hesaplanma şekli her bir geometrik şekil için farklı olacağından bu metotların içeriklerinin detayları arayüzü uygulayacak sınıflara bırakılmıştır. Zaten arayüz kavramı ile böyle bir içerik tanımlamasının mümkün olmadığını daha önce belirtmiştik.

/* SekilHakkindaBilgi.java */

public interface SekilHakkindaBilgi {

public double cevreGoster();

public double alanGoster();

}

Arayüzler, programcılar tarafından gerekli durumlarda oluşturulabilir. Bununla birlikte, Java standart kütüphanesi içerisinde de kullanılabilir hazır arayüzler mevcuttur. Aşağıda kodları verilen Insan sınıfı Comparable adlı Java kütüphanesi arayüzünü uygulayan bir sınıftır. Bu sınıfın içerisinde, compareTo isimli metodun içeriğinin tanımlandığını görmekteyiz. Bu metot, Comparable arayüzü içerisinde tanımlı olan ve int türünde değer döndürmesi beklenen bir metottur. Karşılaştırılan iki nesnenin birbirinden büyük veya küçük olması durumunda bu metodun 1 veya -1 döndürmesi beklenir. Eşitlik durumunda ise 0 değerini döndürmesi beklenmektedir.