ÖNEMLİ : Kendim için aldığım notlar. Umarım size de bir faydası olur. Kullanılan her bir makale referans olarak eklenmiştir.
Java’da Kalıtım(inheritance) ve Java’da Polimorfizm Serisi
- Java’da Kalıtım 1 - Kalıtımı Neden Kullanırız? Kalıtımı Sağlamak İçin Asgari Şartlar Nelerdir?
- Java’da Kalıtım 2- Extends
- Java’da Kalıtım 3 - Referans ve Nesne Tipleri
- Java’da Kalıtım 3.1 - Static ve Dinamik Tür
- Java’da Kalıtım 4 - Görünürlük/Erişim Değiştiricileri
- Java’da Kalıtım 5 - Java’da Nesne Oluşturma
- Java’da Kalıtım 6 - Sınıf İnşası için Derleyici Kuralları
- Java’da Kalıtım 7 - Sınıf Hiyerarşisinde Değişken İlklendirme
- Java’da Kalıtım 8 - Alıştırmalar
- Java’da Kalıtım 9 - Overriding(Ezici) Metotlar
Genel Bakış
Bir önceki bölümden de hatırlayacağımız üzere yazdığımız kodda tutarlılığı sağlamak ve veri yapısını tek bir sınıfta toplamak için belirlediğimiz temel hedefler şunlardı;
Kodda tutarlılığı sağlamak ve veri yapısını tek bir sınıfta toplamak için hedefler:
- Bütün ortak davranışları bir sınıfta tutmak,
- Farklı davranışa sahip olanları ise farklı sınıflara ayırmak
- Tüm bu nesneleri tek bir veri yapısında tutmak.
İlk iki hedefi bu bölümde ele almaya çalışacağız. Hatırlayacağınız üzere, bunu java’da kalıtım(inheritance) kullanarak çözmeye çalışacağımızı belirtmiştik.
Java’da extends anahtar kelimesine bir örnek
Java extends anahtar kelimesinden yoksun bir örnek
Ortak Kod
1 2 3 4 public class Person { private String name; .... }
Farklı Sınıflara Ayrılan Kod
1 2 3 4 5 6 7 8 9 public class Student { private String name; .... } public class Faculty { private String name; .... }
Aslında 1 ve 2. seçenekleri tamamlamamız için sihirli bir anahtar kelimesine ihtiyacımız bulunmaktadır. Çünkü ortak değişkenler hâlen tek bir sınıfta ikamet ediyor. Tahmin edeceğiniz üzere bu kelime extends anahtar kelimesidir.
Java extends anahtar kelimesiyle bir örnek
Ortak Kod
1 2 3 4 public class Person { private String name; .... }
Farklı Sınıflara Ayrılan Kod
1 2 3 4 5 6 7 public class Student extends Person { .... } public class Faculty extends Person { .... }
Görüleceği üzere ortak değişkenimiz olan name, sadece üst sınıfımız olan Person sınıfında yer almaktadır. Ama private erişim değiştiricisine sahip!!!
Bu arada extend anahtar kelimesinin anlamı genişletmektir. Yalnız programlama jargonundaki tam karşılı ise miras almaktır. Yani Student ve Faculty sınıflarını Person sınıfına extends ettiğimizde aslında Person sınıfını miras almış oluruz.
Peki Java’da parent sınıftan ne miras alınır?
Tabii ki bütün özelliklerini değil!
- public örnek değişkenleri(instance variables) ve statik değişkenleri miras alırız,
- public metotları miras alırız,
- private örnek değişkenleri de teknik olarak miras alınır ama bu değişkenlere erişim için public metotlara ihtiyacımız olacaktır. Aşağıda bunu izah etmeye çalışacağım.
- kurucular (constructors) miras alınmaz. (Fakat, Java kuralları, tüm kurucuların üst sınıfın kurucularından birine çağrı yaparak başlaması gerektiğini söyler. Bunun cevabını şu yazımda bulabilirsiniz.)
- nested sınıfları miras alırız.
Not: Dikkat edecek olursanız, üst sınıfımız olan Person sınıfında bulunan name ismindeki üye değişkenimiz private erişim değiştiricisine sahip olduğu için alt sınıflar tarafından miras alınsa da bu değişkene erişim şu an için mümkün gözükmemektedir.
Kaldığımız yerden devam edecek olursak, Person sınıfımız bizim base/super/parent sınıfımız olurken, Student ve Faculty sınıfları ise ana sınıftan türeyen derived/subclass/child sınıfları olur.
Gizli değişken (Hidden Variable) | Gölge değişken (shadow variable / variable shadowing)
Bu örnekte ise hem parent hem de child sınıfta, name isminde benzer üye değişkenlerimiz bulunmaktadır. Görüleceği üzere, her ikisi de private erişim değiştiricisine sahip. Sizce Student sınıfında name adında private bir üye değişkenine gerçekten de sahip olmanız gerekiyor mu?
Aslında hayır… Hatta bu kötü bir pratiktir.
Çünkü, Student sınıfı içindeki private name değişkeni, gizli değişken veya gölge değişken (variable shadowing) olarak ifade ettiğimiz şekilde davranır. Yani hangi sınıfın name üye değişkeninden bahsettiğinizi belirlemek zordur. Student mı yoksa Person mı? Bu yüzden Student sınıfı içinde tekrardan aynı isimli bir değişkeni tanımlamamız anlamsızdır, çünkü bu değişkeni otomatik olarak Person sınıfından zaten miras alırsınız.
Java’da private örnek değişkenine erişim nasıl sağlanır?
Peki private olan bu örnek değişkenlerini miras alabiliyorsak bunlara nasıl erişeceğiz?
private örnek değişkenlerine doğrudan erişim sağlayamasak da public metotlar üzerinden bu değişkenlere erişim sağlayabiliriz.
getter ve setter metodlar buna güzel bir örnektir. Hatta bu erişim yöntemi şiddetle tavsiye edilir.
1 2 3 4 5 6 7 8 9 10 11 12 public class Person { private String name; public String getName(){ return name; } .... } public class Student extends Person { ... }
Java Miras Hiyerarşisinin UML Diagramı
Artık mirası nasıl kullanabileceğimiz hakkında bir fikrimiz olduğuna göre, bir miras hiyerarşisini nasıl tasarlayabileceğimiz hakkında konuşmaya başlayalım. Şimdi bir tasarım ekibi ile bir beyaz tahta üzerinde çalışıyorsanız, tüm sınıfı yazmak istemeyeceksiniz. Bir sınıfı çok küçük bir şekilde temsil etmek isteyeceksiniz.
Kalıtım(inheritance) hiyerarşisi şu şekildedir.
-
Grade Point Average (Not Ortalaması)
-
Salary(Maaş)
-
Gender(Cinsiyet)
Diyelim ki yukarıdaki 3 değişkeni bu sınıflara eklemek istiyorsunuz. Sizce hangisi hangi sınıfa daha uygun olur? Örneğin Student sınıfına ait olup ama Faculty sınıfında olmayan değişken ne olabilir? Aynı soruyu Faculty sınıfına ait olup ama Student sınıfında olmayan şeklinde tersten de sorabiliriz.
Cinsiyet değişkeni genel bir değişken olduğundan Person sınıfında olması daha doğru olacaktır. Ama maaş ve not ortalaması değişkenleri biraz daha spesifiktir. Yani öğrencinin maaş alamayacağını ve öğretim görevlilerinin ise not ortalamasına sahip olamayacağını biliyoruz. Bu yüzden bu değişkenleri bu sınıflara özel olarak tanımlayabiliriz.
Bölümün başında belirttiğimiz 3 şarttan ilk ikisini gerçekleştirdik. Sonuncuyu ise bir sonraki yazımda ele aldım, dilerseniz bakabilirsiniz.