abstractbir sınıf ve metot yazmak ve bunları alt sınıflarda gerçekleştirmek- Bir arayüz tanımlamak ve bir sınıfta birden fazla arayüzü gerçekleştirmek
- Soyut sınıf ile arayüz arasında seçim yapmak
Önceki dersteki Shape sınıfına tekrar bakalım: area() metodu 0 döndürüyordu. Peki “sadece bir şekil” nedir ve alanı neden sıfır olsun? Aslında new Shape() oluşturmanın hiçbir anlamı yoktur; Shape yalnızca genel bir fikirdir. Java bu tür fikirleri ifade etmek için iki araç sunar: soyut sınıflar ve arayüzler.
Soyut sınıflar
abstract olarak tanımlanmış bir sınıftan nesne oluşturulamaz; o yalnızca alt sınıflar için bir temeldir. Soyut bir sınıfta soyut metotlar bulunabilir: bunların başlığı vardır ama gövdesi yoktur. Her alt sınıf bu metotları mutlaka gerçekleştirmelidir. Bununla birlikte soyut bir sınıfta sıradan alanlar, yapıcılar ve hazır metotlar da olabilir.
public class Main {
public static void main(String[] args) {
Payment[] payments = { new CardPayment(50), new CashPayment(20) };
for (Payment p : payments) {
p.process();
}
}
}
abstract class Payment {
protected double amount;
Payment(double amount) { this.amount = amount; }
abstract double fee();
void process() {
System.out.println(getClass().getSimpleName() + ": " + amount + " + fee " + fee() + " = " + (amount + fee()));
}
}
class CardPayment extends Payment {
CardPayment(double amount) { super(amount); }
@Override double fee() { return amount * 0.02; }
}
class CashPayment extends Payment {
CashPayment(double amount) { super(amount); }
@Override double fee() { return 0; }
}CardPayment: 50.0 + fee 1.0 = 51.0 CashPayment: 20.0 + fee 0.0 = 20.0
Payment sınıfı bir ödemenin nasıl işlendiğini bilir (process metodu), ama komisyonun ne kadar olduğunu bilmez; bunu her ödeme türü kendisi söyler. getClass().getSimpleName() nesnenin gerçek sınıfının adını döndürür. new Payment(10) yazarsan derleyici şu hatayı verir: Payment is abstract; cannot be instantiated.
Arayüzler
Bir sınıfın neler yapabildiğini tanımlayan bir sözleşme: genellikle gövdesiz metotlardan oluşan bir liste. Sınıf, implements anahtar kelimesiyle arayüzü gerçekleştirir ve tüm soyut metotlarını yazmak zorundadır.
Bir sınıf yalnızca bir sınıftan türeyebilir, ama istediği kadar arayüzü gerçekleştirebilir. Ördek hem uçabilir hem yüzebilir, uçak ise yalnızca uçabilir; oysa ortak bir üst sınıfları yoktur. Java 8'den beri arayüzlere gövdesi olan varsayılan (default) metotlar da yazılabilir: sınıf bunları olduğu gibi kullanabilir ya da geçersiz kılabilir.
public class Main {
public static void main(String[] args) {
Duck duck = new Duck();
Plane plane = new Plane();
Flyable[] flyers = { duck, plane };
for (Flyable f : flyers) {
f.fly();
f.land();
}
duck.swim();
}
}
interface Flyable {
void fly();
default void land() {
System.out.println(" ...landing safely");
}
}
interface Swimmable {
void swim();
}
class Duck implements Flyable, Swimmable {
public void fly() { System.out.println("Duck flaps its wings"); }
public void swim() { System.out.println("Duck swims in the lake"); }
}
class Plane implements Flyable {
public void fly() { System.out.println("Plane starts its engines"); }
@Override
public void land() { System.out.println(" ...landing at Heydar Aliyev Airport"); }
}Duck flaps its wings ...landing safely Plane starts its engines ...landing at Heydar Aliyev Airport Duck swims in the lake
Comparable: standart kütüphaneden bir arayüz
Java'nın kendi kütüphanesi de arayüzler üzerine kuruludur. Arrays.sort() sayıları ve karakter dizilerini sıralamayı bilir; peki ya kendi nesnelerin? Bir sınıf Comparable<Product> arayüzünü gerçekleştirir ve compareTo metodunu yazarsa Arrays.sort() onu da sıralayabilir. compareTo negatif bir sayı döndürürse o anki nesne önce gelir, pozitif bir sayı döndürürse sonra gelir; 0 ise eşitlik demektir.
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
Product[] cart = {
new Product("Laptop", 1500),
new Product("Pen", 1.2),
new Product("Backpack", 45)
};
Arrays.sort(cart);
System.out.println(Arrays.toString(cart));
}
}
class Product implements Comparable<Product> {
private final String name;
private final double price;
Product(String name, double price) {
this.name = name;
this.price = price;
}
@Override
public int compareTo(Product other) {
return Double.compare(this.price, other.price);
}
@Override
public String toString() { return name + " " + price; }
}[Pen 1.2, Backpack 45.0, Laptop 1500.0]
Hangisini seçmeli?
| Özellik | Soyut sınıf | Arayüz |
|---|---|---|
| Anahtar kelime | extends | implements |
| Kaç tane kullanılabilir? | yalnızca bir | istenen sayıda |
| Alanlar | her türlü alan | yalnızca sabitler |
| Yapıcı | olabilir | olamaz |
| Anlamı | “bir …dır” (kartla ödeme bir ödemedir) | “…ebilir” (ördek uçabilir) |
Önemli noktalar
abstractbir sınıftan nesne oluşturulamaz; soyut metotlarını alt sınıflar gerçekleştirir.- Arayüz, bir sınıfın neler yapabildiğini belirten bir sözleşmedir; sınıf onu
implementsile gerçekleştirir. - Bir sınıf tek bir sınıftan türeyebilir ama birçok arayüzü gerçekleştirebilir.
defaultmetotların arayüzün içinde hazır bir gövdesi vardır.ComparablevecompareTo, kendi nesneleriniArrays.sort()ile sıralamanı sağlar.
Kendini test et
10 soru. Her doğru cevap XP kazandırır.
abstract class Animal için hangi satır derlenmez?