Interface’lerin Mantığı Nedir(1)?(Hikayeli)

Mehmet Fatih Ercik
Codable
Published in
6 min readMay 17, 2019

Üniversiteden mezun olduktan sonra interface ve abstract kavramlarını biri sorarsa takır takır cevap veriyordum. İşte Animal class’ı var, buna extend etmiş Cat ve Dog class’ları var, Animal class’ı bir abstract class’tır falan. Birde Shape diye bir class var bunu kullanınca her şey daha güzel oluyor. Dairede, Kare her türlü şekli çizebilirsin.

Gel görki interface’i nerede kullanacağımı bir türlü kafamda oturtamıyordum. Madem interface’in metotlarını, gidip class’ın içinde yazacaksak neden birde interface oluşturuyoruz. Direkt bir class oluşturalım içerisine metotları yazalım olsun bitsin.(O zamanda DRY(Dont repeat Yourself) prensibinin mantığını çözmüştüm.)
Tabi zamanla interface’lerin mantığını öğrendim. Aslında interface ve abstract kavramını anlamak için daha önce başkalarının yazdığı kodları incelemek gerekiyormuş. Animal,Cat, Shape, Kahve Makinası kavramları üzerinden anlatılınca çok havada kalıyor. Bunların gerçek hayatta nerelerde kullanıldığını görmek gerekiyor.

Daha sonra tanıştığım bir çok yeni mezun arkadaşın benim demin anlattığım durumumda olduğunu gördüm. Yani hepsi basit örnekler üzerinden bu kavramları gayet iyi açıklıyorlar ama bir yerde interface kullanıldığını görünce “Hayret vallahi” diyorlar.

Bende bu yazıda interface’in tanımı,abstract class’tan farkları falan filan bunlardan bahsetmeyeceğim. Naçizane interface kavramının mantığını anlatmaya çalışacağım. Bu yazı, daha çok interface kavramını yeni oturtmaya başlayanlara hitap ettiği için basiten zora gidecek şekilde ilerlemeye çalıştım.

Bu konuyu iki makale şeklinde anlatacağım. İlk makale olan bu yazıda bazı tanımlamalar yaparak, bu tanımlar arasındaki ilişkiyi anlatmaya çalışacağım.

İlk Makalenin İçeriği:

  • Class ve interface tanımlarını hatırlatma
  • Polimorfizm kavramını kısaca değinme
  • Küçük bir hikaye ile yukarıdaki class, interface ve polimorfizm kavramlarının birbirleri ile ilişkilerini anlatma

İkinci makalede interface kavramının daha iyi anlaşılabilmesi için bir örnek vereceğim. Basit örneklerden ziyade, Java kaynak kodunda interfacelerin nasıl kullanıldığını gösteren bir örnek üzerinden ilerleyeceğim.

Öncelikle temel bazı şeyleri hatırlayarak başlayalım.

Class nedir ve ne işe yarar?

Class OOP temel taşı olup tip(type) tanımlamak için kullanılır. Class, oluşturulacak objelerin hangi özelliklere ve hangi metotlara sahip olduğunu ve bu metotların nasıl çalışacaklarını tanımladığımız yerdir.
Bir class sadece ve sadece bir class’a exteds edebilir.(extends kelimesi çok pahalı bir kelimedir. sadece bir class için kullanılabilir.)
Bir class bir çok interface’i implement edebilir.

Interface nedir işe yarar?

Interface normal bir class gibi tip(type) tanımlamak için kullanılır. İçerisindeki default ve static tanımlanan metotlar hariç, metotların implementasyonları bulunmaz ve state tutmaz.
Bir çok class tarafından implement edilebilirler. Birden fazla interface’i extend edebilirler.
Normal class’tan farkları vardır ama yazımızın konusu olmadığı için burada değinmeyeceğim. Buradaki en önemli nokta interfacin de tip(type) tanımlamak için kullanıldığıdır.

Polimorfizm

Class ve Interface kavramları ile ilgili küçük hatırlatmadan sonra OOP temel konseptlerinden olan polimorfizme geçebiliriz.

Polimorfizm bir objenin birden fazla tipte(type) bulunabilmesidir. Tip dönüşümleri casting ile yapılır. Bir obje o anda bulunduğu tipin özeliklerini ve metotlarını kullanabilir. Tipler(type) class ve interface kullanılarak tanımlanır.
Bu küçük hatırlamadan sonra polimorfizmi daha iyi anlamak için size bir hikaye anlatayım.

Bana Bir Hikaye Anlat

Yıllar yıllar evvel uzak bir kasabada mutlu bir aile yaşarmış: Koçovalı ailesi. Koçovalı ailesinin reisi olan İdris Koçovalı çevresindeki insanlar tarafından sevilip sayılan, herkesin hürmet ettiği bir delikanlıymış. Bir gün ava giden İdris, gölgede yatan bir ayı görünce korku ile kaçmış ve ayağı takılarak YAMAÇ’tan aşağıya düşmüş. Yamacın aşağısında, papatya toplayan güzel köylü kızının ayaklarının dibine kadar yuvarlanmış. Güzel köylü kızı kan revan içerisindeki İdris’i evine götürerek yaralarını sarmış. İyi kalpli eşi Sultan hanım ile tanışmaları bu şekilde olmuş.

Koçovalı ailesi,dünyaya bir erkek çocuk getirmek için gün sayıyormuş. Saydıkları günler bittikten sonra :), dünyalar güzeli bir erkek bebekleri olmuş.
Bir yamacın dibinde tanıştıkları için bebeklerine YAMAÇ ismini vermişler.

İdris, oğlunu nüfusa kaydettirmek için, mutlu ve heyecanlı bir şekilde hükumet konağının yolunu tutmuş.
Kayıt işlemi bittikten sonra , nüfus memuru İdris’in eline oğlunun NufusCuzdani uzatmış.

Yamaç serpilmiş büyümüş ilk okula gidecek yaşa gelmiş. Babası ve annesi çocuklarını okulun ilk gününde yalnız bırakmamışlar. Yamaç Cumhuriyet İlk Okulu’nun 1-B sınıfının öğrencisi olarak ilk derse annesi ile birlikte girmiş. İdris okuldan üzerinde Okul adı, sınıfı ve okul numarası olan bir OgrenciKarti almış.

Yamaç, bir gün babası ile birlikte, öğrenci yolcu taşıma kartı almak için belediyenin yolunu tutmuşlar. İdris, uzun kuyruğun ön tarafında bulunan bir arkadaşının yardımı ile araya kaynamış.(Yamacın ileride it kopuk olmasının sebebi). Sıra kendilerine geldikten sonra belediye görevlisi Yamaç’ın OgrenciKarti’ını ve 1 adet fotoğrafını istemiş.
Yamacın öğrenci olduğuna kanaat getirdikten sonra indirimli YolcuKartı düzenleyip Yamaç’ın eline vermiş.

Yıllar yılları kovalamış , Yamaç büyümüş deli kanlılık yaşına gelmiş. Yamaç araba kullanmakta çok istekliymiş. Bir gün arkadaşı tas kafalı Meke ile birlikte Meke’nin babasının arabasını alıp götürmüşler. Yol üzerinde çevirme yapan polisler, yamacın sürdüğü aracı durdurmuşlar.
Yamacın SurucuEhliyeti olmadığı için Yamaç ve arkadaşı Meke’yi araba ile bilikte karakola götürmüşler.(Hikayenin sonu gelmiyor bu kadar yeter)

Hikayeden Konuya

Hikayemizin konumuzla bağlantısını yapacak olursak. Yamacın doğumu yeni bir class’ın oluşturulmasıdır.(Obje değil. Yeni class yazmaya başladık.) Yamaç class’ı Insan class’ına extend eder.(type=Insan,Yamac)

public class Yamac extends Insan {
........
}

İdris’in Yamaç için kimlik kartı çıkarması yamaç class’ının NufusCuzdani interface’ini implement etmesidir.(type=Insan, Yamaç, NufusCuzdani) Kimlik kartının üzerindeki bilgiler herkes tarafından doldurulmalı, yani interface’in bütün metotları implement edilmeli. (Farklı vatandaşlıklar için farklı interfaceler.)
NufusCuzdani’nın üzerindeki alanların doldurulması, kimlik kartındaki metotların implement edilmesidir. (getAd, getSoyad vb)

public interface NufusCuzdani{
public String getAd()
public String getSoyad()
public String getSehir()
public Date getDogumTarihi()
}

Yamaç’ın okula başlaması ile OgrenciKarti interface’i implement edilir.(type=Insan, Yamaç, NufusCuzdani,OgrenciKarti). OgrenciKarti interface ’i NufusCuzdani interface’ine extend eder. NufusCuzdani interface’indeki metotlar daha önce implement edilmiştir. Dolayısıyla sadece OgrenciKarti’ndaki metotlarının (OkulAdı= Cumhuriyet İlk Okulu, Sınıf=1-B Sınıfı) implement edilmesi yeterlidir.

public interface OgrenciKarti extends NufusCuzdani{ 
Okul getOkul()
Sinif getSinif()
String getOkulNumarasi()
}

Belediye görevlisi, YolcuKartı vermek için Yamaç objesini OgrenciKarti tipine cast ederek Yamacın öğrenci olduğuna kanaat getirmiştir. Görevli sadece OgrenciKarti üzerinde bulunan metotları kullanabilir.
Yani yamacın en sevdiği oyuncak bilgisine OgrenciKarti’na bakarak bilemez.
Görevli OgrenciKarti’ndaki metotların implementasyonu ile ilgilenmez; Yamaç isminin nasıl verildiği görevli için önemli değildir.

interface YolcuKarti extends NufusCuzdani{ 
INDIRIM_TIPI getKartTipi() //OGRENCI,YASLI,NORMAL,AYLIK
BigDecimal getBakiye()
}

Polis, Yamaç objesini SurucuEhliyeti tipine cast etmeye çalıştığında cast edememiş ve ClassCastException hatası fırlatılmıştır. Bu hatanın sebebi Yamac class’ının SurucuEhliyeti interface ’ini implement etmemesidir. Polis, bir objesinin özellikle SurucuEhliyeti tipinde olmasını beklemektedir. Yani öğrencimi(String), yolcu mu(Integer), solcu mu(Double),erkek mi kadın mı(ArrayList), yada başka birşey mi buna bakmaz. İlgilendiği tek şey Şoförün SurucuEhliyeti’inin olmasıdır.

public interface SurucuEhliyeti extends NufusCuzdani{ 
public EHLIYET_SINIFI getSinifi() // A,A2,B,E,D
public void arabaKullan()
}

Burada Yamaç class’ı bir çok tipe dönüştürülebilir. Interface’ler de bir tip tanımladığı için implement edilen Interface’lerin tipine de cast edilebilir.

Bir toplulukta SurucuEhliyeti olan var mı? denildiğinde faklı insanlar(class’lar) el kaldırır. Bütün bu insanların ortak özelliği SurucuEhliyeti’lerinin olmasıdır. Yani bütün bu farklı objeler SurucuEhliyeti interface’ini implement ettikleri için SurucuEhliyeti tipine cast edilebilir. Cast edildikten sonra sadece SurucuEhliyeti üzerindeki metotları(arabaKullan) çağırabilir.

Hikaye ile, bir objenin birden fazla tipe dönüşebileceğini, casting yapan objenin(Polis veya Belediye Görevlisi) sadece cast edilen tipteki metot ve alanlara erişebileceğini, Interface’lerin farklı class’lar arasında ortak bir bağ kurmak için kullanıldığını anlatmaya çalıştım.

Özetle Polimorfizm hem interface’ler hemde abstract class’lar vasitası ile yapılır. Genelde verilen Animal,Cat ve Dog örneklerinden dolayı polimorfizmin interface’ler kullanılarak da yapılabileceği gözden kaçıyor.

Hikayede anlatılan objelerin ve bunların olası metotları aşağıda bulunmaktadır. Bu class’ları incelemeniz konunun daha iyi anlaşılmasına yardımcı olacaktır.

Insan class’ı:

Insan Class’ı

Interface’ler:

Interface’ler

Yamaç Class’ı

Yamaç Class’ı

Bu yazıda özetle;

  • Interfacele’rin de tip(type) yaratmak için kullanıldığını
  • Polimorfizm’in bir objenin bir den fazla tip te bulunması olduğunu
  • Interface’lerin farklı class’lar arasında ortak bir bağ kurmak için kullanıldığını
  • Casting yapan objenin(Polis veya Belediye Görevlisi) sadece cast edilen tipteki(SurucuEhliyeti, OgrenciKarti) metotlara erişebileceğini

anlatmaya çalıştım.

Bu serinin ikinci kısmında Interface’lerin kullanımını, JDK da bulunan Comparator, Comparable interfaceleri üzerinden örnekleyerek, gerçek hayatta nasıl kullanıldığını anlatmaya çalışacağım.

İkinci kısım için tıklayın

--

--