Modül dersleri (2/2)
Polimorfizm ve Soyut Sınıflar
Çok biçimlilik ve soyut sınıflar, belirli uygulamalardan bağımsız olarak esnek, genişletilebilir kod yazmamıza olanak tanıyan gelişmiş nesne yönelimli programlama kavramlarıdır.
Polimorfizm
Polimorfizm (birçok biçim) terimi, farklı sınıflardaki nesneleri ortak bir türe aitmiş gibi ele alma yeteneğini ifade eder. Java'da bir üst sınıf referans değişkeni, alt sınıflarından herhangi birinin bir nesnesine referansı saklayabilir.
class Animal {
public void makeSound() {
System.out.println("Verso...");
}
}
class Dog extends Animal {
public void makeSound() {
System.out.println("Woof");
}
}
class Cat extends Animal {
public void makeSound() {
System.out.println("Miao");
}
}Polimorfizm sayesinde şunu yapabiliriz:
Animal myAnimal1 = new Dog(); // Polymorphism
Animal myAnimal2 = new Cat(); // Polymorphism
myAnimal1.makeSound(); // Executes Dog's method (Woof)
myAnimal2.makeSound(); // Executes Cat's method (Miao)Hangi yöntemin çağrılacağına ilişkin karar çalışma zamanında (Geç Bağlama veya dinamik dağıtım) referans değişkenin türüne değil, gerçek nesneye göre verilir.
Soyut Sınıflar (abstract)
soyut sınıf, doğrudan örneklendirilemeyen abstract anahtar kelimesiyle işaretlenmiş bir sınıftır (new MyAbstractClass() yapamazsınız). Diğer sınıflar için "kısmi şablon" görevi görür.
Soyut Yöntemler
Soyut bir sınıf soyut yöntemler içerebilir: gövde olmadan bildirilen yöntemler (küme parantezleri ve kod yok), noktalı virgülle biter. Soyut olmayan alt sınıflar, devralınan tüm soyut yöntemleri uygulamak için gereklidir.
abstract class Shape {
String color;
// Abstract method (no body)
public abstract double getArea();
}
class Circle extends Shape {
double radius;
public Circle(double radius) {
this.radius = radius;
}
// Required to implement getArea
@Override
public double getArea() {
return Math.PI * radius * radius;
}
}Dinamik Bağlama / Geç Bağlama
Java çalışma zamanında hangi yöntemin çalıştırılacağını nasıl biliyor? Bu işlem Geç Bağlama (veya Dinamik Bağlama) olarak bilinir. Aşırı yüklemenin (derleme zamanında çözümlenen) aksine, derleyici hangi yöntemin yürütüleceğini bilmez. Bunun yerine genel bir çağrı talimatı oluşturur. Çalışma zamanında Java Sanal Makinesi (JVM), bellekteki gerçek nesneyi inceler ve o nesnenin sınıfında tanımlanan yöntem uygulamasını çağırır.
Soyut Sınıflar ve Eksik Uygulama
Bir alt sınıf soyut bir sınıftan miras alıyorsa iki seçeneği vardır:
- Tüm soyut yöntemleri uygulayın: bu durumda alt sınıf normal (somut) bir sınıf olabilir ve somutlaştırılabilir.
- Kendisini soyut olarak bildirin: alt sınıf, devralınan tüm soyut yöntemler için bir uygulama sağlamıyorsa,
abstractanahtar sözcüğüyle de bildirilmelidir.
abstract class Animal {
public abstract void makeSound();
}
// This class MUST be abstract because it does not implement makeSound()
abstract class Canine extends Animal {
// Inherits makeSound() but does not implement it
}Kendin dene
Shape türünde bir değişken bildirin ve polimorfizmi kullanarak ona yeni bir Circle nesnesi atayın.
İpucu göster
Temel türü referans türü olarak kullanmak için `Shape s = new Circle();' yazın.
3 denemeden sonra çözüm mevcut
Shape sınıfını soyut yapın ve soyut yöntemi double getArea()'yı ekleyin. Ardından Shape'i genişletecek ve getArea() işlevinin side * side dönüşünü uygulayacak şekilde Square'i tamamlayın.
İpucu göster
Shape'de `public abstract double getArea();` değerini bildirin. Square'de `@Override public double getArea() { return side * side; }`.
3 denemeden sonra çözüm mevcut
Ana yöntemde, yarıçapı 2,0 olan bir Circle nesnesi ve kenarı 3,0 olan bir Square nesnesi içeren Shape[] türünde bir dizi bildirin. Daha sonra getArea() yöntemini çağırarak her şeklin alanını yazdırmak için bir döngü (her biri için veya her biri için) kullanın.
İpucu göster
Diziyi 'Shape[] şekiller = { new Circle(2.0), new Square(3.0) };' ile bildirin ve 'for (Shape s : Shapes)' yazdırma 's.getArea()' kullanarak dizide döngü yapın.
3 denemeden sonra çözüm mevcut