Inheritance / Miras Alma
Tanımlamalar
Subclass/derived class/extended class/child class
Bir sınıftan türetilen sınıfa altsınıf denir.
Superclass/base class/parent class: kendisinden
bir sınıf türetilen sınıf üst sınıftır.
Tüm sınıflar Object sınıfından türetildiği için aslında
tüm sınıflar alt sınıftır. Kendisinden bir sınıf
türetildiğinde üst sınıf olur. Sadece object sınıfının
bir superclass’ı yoktur.
Bir subclass’ın sadece bir adet superclass’ı (object
hariç) olabilir.
Sınıf Hiyerarşisi
Object Sınıfı
Her sınıfın sadece bir superclass’ı bulunabilir yani
bir subclass sadece türetildiği sınıfın bazı
metodlarına ve üyelerine erişebilir.
Fakat object sınıfı hiyerarşinin en üstünde yer
aldığı için her sınıf doğrudan veya dolaylı olarak
bu sınıftan türetilmiştir.
Bunun anlamı toString, clone, finalize, hashcode,
getClass gibi metodlar bir sınıfta tanımlanmamış
olmasına rağmen bu sınıftan üretilen nesneler
tarafından kullanılabilmektedir.
Object Sınıf Metotları
equals()
Nesne referanslarının aynı olup olmadığını kontrol etmek
için kullanılır. Farklı nesneler için çalışmaz.
getClass()
Nesnenin örneklendiği sınıf hakkında bilgi elde etmek için
kullanılır.
hashCode()
Nesnenin benzersiz kodunu elde eder. Bu kod nesnenin
hafızadaki hexadecimal adresidir.
toString()
Nesnenin string gösterimini elde etmek için kullanılır.
Diğerleri
public final void notify()
public final void notifyAll()
public final void wait()
public final void wait(long timeout)
public final void wait(long timeout, int nanos)
Bu metodlar bir programdaki threadleri (iş
parçacıklarını) senkronize etmek için kullanılırlar.
Thread konusuna gelinebilirse detaylı olarak
anlatılacak.
Bicycle superclass’ı
MountainBike subclass’ı
MountainBike alt sınıfı yeni bir alan ekleyerek Bicycly
sınıfının tüm üyelerini (3 alan, 4 metot) miras almıştır
ve 1 yeni alan ve metot eklemiştir. Kurucu metodlar
devralınamaz.
Miras almak yerine yeni bir MountainBike sınıfı 4 alan,
5 metot ve 1 kurucu metot ile tekrar yazılabilirdi ve
miras alma işi bir şekilde kotarılmış olurdu. Fakat;
1. Fazladan kodlama
2. Eğer üst sınıfta karmaşık işler yerine getiriliyorsa
metotların test ve debug edilmesi oldukça
zorlaşacaktı.
Bir alt sınıfta neler
yapılabilir?
Bir alt sınıf üst sınıfı ile aynı pakette ise
Protected, public ve package-private üyeler miras
alınır.
Farklı pakette iseler
Sadece protected ve public üyeler miras alınır.
Paket farkı gözetmeksizin
private üyeler miras alınamaz.
Fakat private üyelere erişimin public üyelerle
yapıldığı dikkate alınırsa bu herhangi bir ek
maliyete neden olmayacaktır.
1. Miras alınan alanlara doğrudan erişim sağlanır
(sınıfın diğer üyeleri gibi)
2. Superclass ile aynı isme sahip yeni alanlar
tanımlanabilir.(hidding)
3. Superclass’ta olmayan yeni alanlar
tanımlanabilir.
4. Superclass’ın metodları oldukları gibi çağrılabilir.
5. Superclass’taki ile aynı imzaya sahip yeni
nesne/örnek metodu oluşturulabilir (overriding –
üstüne yazma)
6. Yeni static metotlar (superclass’taki ile
aynı imzaya sahip) tanımlanabilir (hidding).
7. Superclass’ta olmayan yeni metotlar
tanımlanabilir.
8. Superclass’ın kurucu metodunu çağıran
Subclassa ait yeni kurucu metotlar
tanımlanabilir. Kurucu metot çağırmak için ya
açık olarak kurucu metot adı yazılır veya
super anahtarı kullanılır.
Casting Objects
public MountainBike myBike = new
MountainBike();
Dağ bisikleti bir bisiklettir (bicycle) ve bir
nesnedir (Object).
Fakat tersi doğru olmayabilir. Bir bisiklet dağ
bisikleti olabilir de olmayabilir de.
Aynı şekilde bir nesne (Object sınıfından
örneklenmiş) bir bisiklet olabilir fakat yüksek
ihtimalle değildir.
Object obj=new MountainBike();
Herhangi bir hataya neden olmaz çünkü her dağ
bisikleti bir nesnedir ve Object tipli bir tanım
buradaki nesneye referans verebilir.
Fakat tersi doğru değildir;
Mountainbike mybike=obj;
Derleyici hatasına neden olur. Çünkü ilk tanımda
dolaylı olarak bir tip tanımı varken ikincide bu tip
tanımı açık şekilde verilmelidir. Çünkü her nesne
bir dağ bisikleti değildir.
MountainBike mybike=(MountainBike)obj;
Şeklinde kesin ve açık olarak nesnenin bir dağ bisikleti
olduğu bildirilmelidir.
Böyle bir cast işleminde hataya neden olmamak için
«instanceof» operatörü kullanılabilir.
if (obj instanceof MountainBike)
{
MountainBike myBike = (MountainBike)obj;
}
Multiple inheritance of state
Bir arayüz birden fazla arayüzden miras alabilirken bir
sınıf birden fazla superclass’tan neden alanları
devralamaz?
Sınıfların arayüzlerden en önemli farklarından birisi
arayüzlerde nesneye ait field olamamasıdır. Ayrıca
sınıflardan nesneler üretilebilirken arayüzlerden
üretilemez. Eğer bir sınıf birden fazla superclass’tan
alanları devralırsa örneklemede, kurucu metotların
çağrılmasında ve metotların örneğin alanlarına
ulaşmasında öncelik problemi oluşur. Ayrıca aynı isimde
alanlar olduğundan dolayı metodun hangisine ulaşacağı
önceden kestirilemez.
Multiple inheritance of
Implementation
Bir sınıfın birden fazla sınıftan metotları
devralmasıdır. Metotlardaki isim çakışması
ve belirsizliği programın düzgün çalışmasını
engeller.
Programcı farkında olmadan aynı imzaya
sahip metodu superclass’lardan birine
eklerse;
Bu durum subclass’larda da var fakat
«overriding» mekanizması ne olacağını
belirlemektedir.
Multiple inheritance of types
Bir nesne birden fazla tipi referanslayabilir.
Kendi sınıfından üretilmiş nesneler veya
kendi sınıfının implemente ettiği arayüzleri.
Ayrıca bir arayüz tipli referans değişkeni bu
arayüzü implemente eden tüm sınıfların
nesnelerini referanslayabilmektedir.
Overriding and Hiding Methods
intance methods
Aynı imzaya ve dönüş tipine sahip
subclass’taki örnek methodu superclass’ın
metodununun üzerine yazabilir. (overriding)
Superclass’ın metodunun üstüne
yazılmasının sebebi bu metodun davranışının
istenildiği şekilde düzenlenebilmesini
sağlamak içindir.
Overriding Static Method
(hiding)
Subclass’ta superclass’taki ile aynı imzaya
sahip bir static metodun üzerine yazılmasıdır.
Buradaki üstüne yazma nesne metodundaki
ile aynı değildir, çünkü subclassta
tanımlanan metod superclass’taki static
metodu saklamıştır.
Statik metodun gizlenmesi ve nesne
metodunun üzerine yazılmasında iki önemli
anlam vardır:
1. Üzerine yazılmış nesne metodunun
versiyonu subclasstaki olarak algılanır.
2. Gizlenmiş static metodun versiyonu ise
nereden çağrıldığına bağlıdır (subclass veya
superclass).
Animal superclass
Cat subclass
Eclipse Örnek (Animal and Cat)
Unutmayın metotların üstüne yazılır.
Alanların değil…
Arayüz Metotlarında Üstüne
Yazma
Arayüzün default methodları ve abstract
metodları da örnek metodlarındaki gibi miras
alınır. Yalnız aynı metod imzasına sahip
methodlar hem üst sınıf/arayüz hem de diğer
arayüzlerde (default) tanımlanmışsa Java
derleyicisi aşağıdaki 2 kuralı uygular:
1. Nesnenin metodu arayüzün default
metoduna tercih edilir.
Horse Class
2. Üzerine yazılmış metodlar yoksayılır. Miras
alıp üzerine yazan son default metod
uygulanır.
Dragon Class
Eğer iki veya daha fazla bağımsız olarak
tanımlanmış default methods varsa veya bir
default method bir abstract method ile aynı
imzaya sahipse Java derleyicisi «You must
explicitly override the supertype methods»
hatası verir.
Car Class
Miras alınan nesne metodları arayüzün
abstract metotlarının üzerine yazabilir.
Mustang Class
Unutmadan: Arayüzdeki statik metotlar asla
miras alınamaz.
Metot üstüne Yazmada
Erişim Belirteçleri
Üzerine yazan metot üstüne yazılan
metodun erişimini genişletebilir fakat
daraltamaz.
Superclass’taki protected metodun
subclasst’a üstüne yazılması ile oluşturulan
yeni metot public olabilir fakat private
olamaz.
Ek olarak
Superclass’taki bir örnek metodunu
subclass’ta bir statik metot olarak
güncellemeye çalışırsanız veya tersi bir
durumda java derleyicisi derleme zamanı
hatası verir.
Subclass’ta overloading herhangi bir etki
yaratmaz, subclassın yeni bir metodu olarak
değerlendirilir.
Defining a Method with the Same Signature as a Superclass's Method
Superclass Instance Superclass Static
Method Method
Subclass Instance Generates a compile-
Overrides
Method time error
Generates a compile-
Subclass Static Method Hides
time error
Gelecek dersler
Polymorphism
Hiding Fields
Super anahtarı
Final Classes and Methods
Abstract Methods and Classes
Polymorphism
Polimorfizm sözlük anlamı biyolojide bir
organizmanın veya türün farklı formlara veya
aşamalar sahip olmasıdır.
Bu prensip nesneye yönelik programlama
konseptine de uygulanabilir.
Programlama dilindeki polimorfizm bir sınıfın
alt sınıfları kendi benzersiz davranışlarını
tanımlayabilir ve parent classın aynı
işlevsellikteki bazı davranışlarını paylaşabilir.
Polimorfizmi bisiklet sınıfları üzerinde
gösterelim.
Bicycle Class
MountainBike subclass
RoadBike subclass
App
Output
JVM’nin nesne metodunu çağırması tip
kullanılarak yapılmaz. JVM nesne için uygun
metodu değişkenin oluşturulduğu kurucu
metodun sınıfını (tipi) kullanarak çağırır.
Bu davranış diğer nesneye yönelik
programlama dillerindeki sanal method
çağrımına karşılık gelir ve polimorfizmin
önemli özelliklerinden biridir.
Daha basit örnek
Alanların Gizlenmesi
Daha önce bahsedildiği gibi superclass ile
subclass’ta aynı isimli alan(field/değişken)
varsa subclass’ta superclass’ın bu alanı
gizlenmiş olur. Tipin gizlemede bir önemi
yoktur. Subclass üzerinden superclass’taki
bu değişkene ulaşmak için basit alan adı
kullanılamaz. Super anahtarının kullanılması
gereklidir.
Genel olarak kod okunurluğunu ve
anlaşılırlığını azalttığı için alan gizleme
tavsiye edilmez.
super Anahtarı
Alanların gizlenmesi ve metotların üzerine
yazılmış olması alt sınıftan basit alan adı
veya metod adı kullanarak üst sınıfın
alanlarını veya metotlarını kullanmayı
engeller.
super anahtarı ile gizlenmiş alanlara (tavsiye
edilmez) veya üzerine yazılmış metotlara
ulaşım sağlanabilir.
Super ornek
Super ile kurucu metod
çağırma
public MountainBike(int startHeight, int startCadence, int
startSpeed, int startGear)
{
super(startCadence, startSpeed, startGear);
seatHeight = startHeight;
}
super();
Not: SuperClass’ın kurucu metodu subclass’ın
kurucu metodunda çağrılmazsa Java derleyicisi
otomatik olarak parametresiz bir superclass
kurucu metod çağrısı subclass kurucu metoduna
ekler. Eğer superclass’ta parametresiz kurucu
metot bulunmazsa derleyici bir hata üretir.
Unutmayın kurucu metot çağrılması subclass’tan
Object sınıfına kadar uzanır. Buna «constructor
chaining» adı verilir.
Final Classes and Methods
Final anahtarı sabit tanımlamak için kullanılmasına rağmen
bir method final anahtarı ile imlenirse miras almada alt
sınıflar bu metodun üstüne yazamazlar.
class ChessAlgorithm
{
enum ChessPlayer { WHITE, BLACK }
...
final ChessPlayer getFirstPlayer()
{
return [Link]; }
…
Final Class
Bir sınıf final olarak imlendiğinde final
sınıftan herhangi bir sınıf hiçbirşey miras
alamaz. Bu sabit sınıflar için anlamlı bir
durumdur. Örneğin String sınıfından hiçbir
sınıf herhangi bir şey devralamaz.
Final Methods vs
Constructors
Kurucu metotlardan çağrılan metodlar
genellikle final olarak tanımlanırlar. Aksi
durumda altsınıflarda bu metodun üzerine
yazılırsa sürpriz sonuçlar elde edilebilir.
Örnek< [Link]>
Abstract Classes and
Methods
Abstract sınıflar abstract anahtar kelimesi ile
imlenirler ve abstract metodlar veya normal
metotlar içerebilir veya içermeyebilirler.
Soyut sınıflar örneklenemezler fakat bu
sınıflardan başka sınıflar miras alabilir.
Bir abstract metot implementasyonu
olmayan, sadece metod imzasına sahip olan
bir metottur.
Bir abstract sınıftan bir sınıf türetildiğinde
genellikle alt sınıf abstract abstract super
sınıfının metodlarını uygular. Eğer
uygulamazsa bu sınıf da abstract olarak
imlenmelidir.
Arayüzlerdeki default veya statik olmayan
metotlar da dolaylı olarak soyut metottur ve
abstract anahtarı arayüzlerde
kullanılmamaktadır fakat kullanılabilir ama
gereksizdir.
Soyut Sınıflar Arayüzlere
Karşı
1. Abstract sınıflarda public, protected,
private alanlar tanımlanabilir.
1. Interfacelerde tanımlanan alanlar public,
static ve final’dır.
2. Abstract sınıfta metod implementasyonu
bulunabilir.
2. Interfacelerde default veya statik değilse
metot implementasyonu bulunamaz.
3. Abstract olsun veya olmasın sınıflarda
single miras alma olabilir.
3. Arayüzlerde ise çoklu miras alma
desteklenir.
Ne zaman Abstract, Ne zaman
Interface?
Yakın ilişkili sınıflar arasında kodunuzu
paylaştırmak istiyorsanız abstract sınıfları
kullanın.
Ortak alan veya metotlar fazlaysa abstract
sınıfları kullanın.
Nesneye ait olan ve statik ve final olmayan
alanlara ihtiyacınız varsa abstract sınıfları
kullanmak isteyebilirsiniz.
İlişkisiz sınıflar arasında bir implementasyon
varsa arayüzler kullanılır. Comparable and
Cloneable arayüzleri birçok ilişkisiz sınıf
tarafından uygulanır.
Özel bir veritipinin davranışını belirlemek
isteyebilirsiniz (onu kimin uyguladığı önemli
değildir).
Çoklu miras almanın avantajlarını kullanmak
isteyebilirsiniz.
Abstract class örnek
Nesneye yönelik çizim uygulamalarında çember,
daire, dikdörtgen, çizgiler, Bezier eğrileri ve diğer
bir çok graphic nesneleri çizilebilir.
Bu nesnelerin hepsi bazı kesin durumlara
(pozisyon, oryantasyon, çizgi rengi, dolgu rengi)
ve davranışlara (moveTo, rotate, resize, draw)
sahiptir.
Bazıları davranışlar (position, fill color, moveTo)
ise aynı implementasyona sahiptir.
Diğerleri ise farklı implementasyon gerektirebilir.
Fakat tüm gragik nesneleri draw ve resize
davranışlarına sahip olmalıdır, yalnız nasıl
implemente edildikleri farklı olabilir.
Bu örnek soyut sınıflar için çok uygundur.
abstract class ve metodlar
abstract class GraphicObject {
int x, y;
...
void moveTo(int newX, int newY) {
...
}
abstract void draw();
abstract void resize();
}
class Circle extends GraphicObject {
void draw() {
...
}
void resize() {
...
}
}
class Rectangle extends GraphicObject {
void draw() {
...
}
void resize() {
...
}
}
Abstract class Arayüzü
Implemente Ettiğinde
abstract class X implements Y {
// implements all but one method of Y
}
class XX extends X {
// implements the remaining method in Y
}
Abstract Sınıfın Üyesi
Bazı alanlar ve metodlar statik olabilir.
Bunların kullanımı için normal sınıflardaki
gibi
[Link]() yordamı
kullanılır.