Inheritance (Kaltım)
Tanım olarak kalıtım bir nesnenin özelliklerinin farklı nesneler tarafından da kullanılabilmesine olanak sağlayan NYP özelliğidir. Klasik öğrenci psikolojisi ben bu konuyu nerede kullanacağım? Öncelikle şunu belirtelim: “eğer uygulama geliştirmezsen, kod yazmazsan ve geliştirdiğin yazılımını daha iyi bir yapıya getirmeye çalışmazsan” bu konuyu hiç bir zaman ihtiyaç duymayacaksın. Bu yazımda kalıtım konusunu bir önceki konu üzerine inşa edip örnek bir uygulama üzerinden konuyu anlatmaya çalışacağım.
Bir senaryo
Bir önceki örneğimizde futbol oyununun temel taşı olan Futbolcu sınıfı oluşturmuştuk. Oyunumuz içine birçok sınıf yaratabileceğimizi belirtmiştik. Şimdi Futbolcu sınıfının yanına Teknik Kadro sınıfını da ekleyelim. Teknik kadro: çalıştırıcılar, teknik direktör ve hatta malzemeciden oluşur. Teknik Kadro sınıfı yaratmayı düşündüğümüzde AdSoyad bilgisi, Moral, Pas Öğretme, Fittness Öğretme ve Konuşma Yeteneği vb. özellikleri olabilir. Bir de metot olsun: “Oyuncu ile Konuş ve Moral Ver”. Bir yenilgi sonrası teknik kadroda bir kişi oyuncuya “Konuşma Yeteneği”ne bağlı olarak moral verebilir. Şimdi sınıfımızı yaratalım.
|
public class TeknikKadro { public string ad_soyad; public int Moral; public int Pas_Ogretme; public int Sut_Ogretme; public int Konusma_Yetenegi; public void Konus_Moral_Ver() { //Futbolcunun moralini Konusma_Yetenegi'ne bağlı olarak arttıracak. //Fultbolcu nesnesinin tetiklenmesi lazım. } } |
Sınıfımız hazır şimdi bir önceki konudaki sınıfa bakın ve kıyaslama yaptıktan sonra yazıyı okumaya devam edin.
Kalıtım
Dikkat ettiyseniz iki sınıf arasında benzerlikler var farklılıklar var. İşte tam bu noktada kod geliştirdiğiniz alana hakim olma (Sistem Analizi ve Tasarımı) ve NYP konularına ihtiyaç vardır. Ben kendime göre bir çözüm üreteceğim, mantıklı olmak kaydıyla farklı çözümlerde üretilebilir. Tekrarlayan bilgilerinden üst bir sınıf oluşturalım, biz bu sınıfa base sınıf diyoruz. Sınıfımızın ismi kişi bilgilerini tutacağı için “kisi” olsun.
|
public class Kisi { public string ad_soyad; public int Moral; public int Konusma_Yetenegi; public void Konus_Moral_Ver() { } } |
ad_soyad ve Moral ortak bilgilerdir. Ayrıca, Konus_Moral_Ver tüm kişiler birbirine yapabilsin. Kişi sınıfımız hazır, şimdi kişiyi base alıp teknik kadro ve futbolcu sınıflarını üretelim.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
public class Futbolcu : Kisi { public int Forma_No; public int Sut; public int Pas; //Birçok değişken ve özellik olabilir. public void pas_ver() { } public void gol_dene() { } } public class TeknikKadro : Kisi { public int Pas_Ogretme; public int Sut_Ogretme; } |
C# “:” katılım işleminde kullanılır. (Java olsaydı extends’ti.) Artık Hem Futbolcu hem de TeknikKadro sınıfları Kisi sınıfının özelliklerini kullanabiliyor. Constructor sayesinde nesne oluşturulurken değişken bilgilerini alabiliyorduk. 3 sınıf içinde birer contructor oluşturalım.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
|
public class Kisi { public string ad_soyad; public int Moral; public int Konusma_Yetenegi; public Kisi(string _as, int _m, int _ky) { ad_soyad = _as; Moral = _m; Konusma_Yetenegi = _ky; } public void Konus_Moral_Ver() { } } public class Futbolcu : Kisi { public int Forma_No; public int Sut; public int Pas; public Futbolcu(string _as, int _m, int _ky, int _fn, int _s, int _p) :base(_as, _m, _ky) { Forma_No = _fn; Sut = _s; Pas = _p; } //Birçok değişken ve özellik olabilir. public void pas_ver() { } public void gol_dene() { } } public class TeknikKadro : Kisi { public int Pas_Ogretme; public int Sut_Ogretme; public TeknikKadro(string _as, int _m, int _ky, int _po, int _so) :base(_as, _m, _ky) { Pas_Ogretme = _po; Sut_Ogretme = _so; } } |
Contructor sınıf ismi ile aynı isme sahip olmalı ve public olmalıydı. Contructor ile değer tetiklemeleri yapılabiliyordu. Ayrıca constructor overloading sayesinde birden fazla contructor tanımlanabiliyordu. (Ders Notlarından ayrıntıya bakılabilir.) Eğer elimizde türeyen bir sınıf var ise (yani base’in özelliklerini barındıran) base contructor’a veri aktarılabilir. Bunun için Contructor ifadesinin parantezlerinden sonra :base(değerler) şeklinde bir tanımlama yapılmalıdır.
Konus_Moral_Ver fonksiyonu üç sınıftanda kullanılabilen bir fonksiyondur. Eğer alt sınıflarda bu metodu değişikliğe uğramasını istersek alt sınıflarda new parametresi kullanabiliriz veya base sınıftaki metodu virtual yapıp alt sınıflarda override edebiliriz. Daha geniş bilgi ders notlarında vardı.
Elimizde üç sınıf var üçünden de new kullanarak türetme işlemi yapabilirsiniz. Ancak Kisi diye bir tanımlamanız yok ise ve yaratılmasını istemeyebilirsiniz. Bu durumda abstract (soyut) sınıflar aklımıza geliyor.
Abstract Sınıf (Soyut Sınıf)
Abstract sınıf base sınıf olarak kullanılır ama yukarıdaki örnekten farklı olarak new ile yaratılamaz. Abstract sınıf içine değişken ve metotlar tanımlanabilir ve alt sınıflarda şart olması gereken metotlar abstract metot olarak tanımlanır. Bu bilgiler ışığı altında yukarıdaki örneğimizi geliştireceğim.
|
public abstract class Kisi { public string ad_soyad; public int Moral; public int Konusma_Yetenegi; public void Konus_Moral_Ver() { //İçinde kodlar var } public abstract void Bilgi(); } |
Abstract sınıf olduğunu class tanımlama bölümde belirtik. Değişkenleri bozmadık. Konus_Moral_Ver fonksiyonu içinde kodlarımız durabilir. Ayrıca, contructor’da tanımlayabiliriz. Ama kesinlikle bu sınıftan new ile nesne yaratamayız.
Futbolcu ve TeknikKadro sınıflarında kalıtım benzer şekilde yapılır. Ancak void olan Bilgi metodu kesinlikle alt sınıflarda tanımlanmalıdır. abstract sınıf içindeki tüm abstract metotlar tanımlanmalıdır. Tanımlama yaparken override yazmak zorundayız.
|
public override void Bilgi() { //kodlarımız olacak } |
Bunu türetilen her iki sınıf içinde kullanmak zorundayız. Abstract Kisi sınıfında değişken ve metotlarımızı tanımlayabiliriz. Bazen öyle bir sınıfı ihtiyacımız olur ki sadece bize kılavuzluk yapmasını isteyebiliriz. Interface (Arayüz) bunun için tasarlanmış bir yapılır.
Interface (Arayüz)
Bir Interface, başka sınıflar için bir rehberdir. Interface’de yaratma olmaz, constructor olmaz, değişken olmaz, erişim belirteçleri yoktur sadece metod isimleri, varsa metod parametreleri ve property’ler yazılır. Interface içindeki metotlara abstract metotta olduğu gibi kesinlik kod yazılmaz. Abtract metotta olduğu gibi interface içindeki tüm metotlar ve property’ler türetilen sınıf içinde yazılmalıdır. Ama abstract’tan farklı olarak metotlar override edilmez. Bir sınıf birden fazla interface içerebilir ama birden fazla abstract sınıf veya base sınıf içeremez. Birden fazla interface için ” : Interface1, Interface2…” şeklinde yapılır. (Java’da interface kullanmak için implements kullanılır.)
Şimdi basit bir interface yapalım.
|
public interface class IKisi { void Konus_Moral_Ver(); void Bilgi(); } |
Eğer IKisi interface’ini Futbolcu ve TeknikKadro sınıflarında kullanırsanız (örneğin public class Futbolcu: IKisi), bu sınıflara iki metoduna tanımlamalısınız. Bu sınıflara kendi metotlarınızı, property ve değişkenlerinizi de tanımlayabildiğinizi unutmayın.
Adım adım kalıtım işlemlerini yaptık. Hepsi birbirine benziyor ama hangisi daha iyi derseniz, seçim uygulama alanına ve tasarım yeteneğinize göre değişir. Yazılım tasarımı tamamen kodlama bilginize ve yeteneğinize kalmış bir olaydır. Tasarım yeteneğini zamanla uygulama geliştirilen ortamı tanıdıkça kazanırsınız. Bir sanatçı gibi kendinize özel bir dünya ve sınıflar hiyerarşisi tanımlayabilirsiniz. Fakat bu dünyayı inşa edebilmek için veya inşa edilmiş dünyaları (örneğin günümüzün popüler konusu MVC gibi) anlayabilmek için temel konuları bilmelisiniz. Biz size tuz, şeker, hamur vs. nedir diye anlatıyoruz, siz pastayı yapacak kişisiniz. Güzel pastalar dilekleriyle…