Bölüm 4: Soyut Sınıflar ve Arayüzler
Çoktan Seçmeli · Soyutlama
Soru 1: Soyutlamanın Amacı
Java’da soyut sınıflar ve arayüzler ortak olarak neyi sağlar?
B: İkisi de soyutlama aracıdır: “ne”yi (metot imzalarını, sözleşmeyi) yukarıda tanımlar, “nasıl”ı alt sınıflara ya da gerçekleştiren sınıflara bırakır. Sınıflarda çoklu kalıtım yoktur (A); ikisinden de new ile nesne oluşturulamaz; çağrılar yine dinamik bağlanır (D).
Çoktan Seçmeli · Soyut Sınıflar
Soru 2: Hangisi Derlenir?
Aşağıdaki tek satırlık tanımlardan hangisi derlenir?
C: Hiç soyut metodu olmayan soyut sınıf geçerlidir (yine de new A() yazılamaz). A: abstract methods cannot have a body. B ve D: illegal combination of modifiers; private ve final geçersiz kılmayı engeller, soyut metot ve soyut sınıf ise alt sınıf için vardır.
Hata Bulma · Soyut Sınıflar
Soru 3: Alan() ≠ alan()
Hangi satırlar derleme hatası verir? Her biri nasıl düzeltilir?
abstract class Sekil { String ad; Sekil(String ad) { this.ad = ad; } abstract double alan(); } class Kare extends Sekil { double k; Kare(double k) { super("Kare"); this.k = k; } double Alan() { return k * k; } } // main içinde: Sekil s = new Sekil("?"); Sekil[] d = new Sekil[2];
Cevabı göster
class Kare:Kare is not abstract and does not override abstract method alan() in Sekil.Alan()(büyük A) yeni bir metottur; soyutalan()hâlâ eksik. Ad düzeltilmeli; üstüne@Overrideyazılırsa bu tür yazım hataları hemen yakalanır.new Sekil("?"):Sekil is abstract; cannot be instantiated. Somut alt sınıf kullanılır:Sekil s = new Kare(3);new Sekil[2]derlenir: nesne değil, iki boş (null) referans oluşturur. Soyut sınıfın yapıcısı olması da geçerlidir.
Adım Adım Çalıştırma · Soyut Sınıflar
Soru 4: Soyut Tip, Somut Nesne
Soyut sınıfın yapıcısı ve somut ozet() metodu var. Program ne yazar?
new Kare(2): Kare yapıcısı super("Kare") ile soyut sınıfın yapıcısını çağırır. Ayrı bir Sekil nesnesi oluşmaz; aynı nesnenin Sekil kısmı kurulur. adet = 1.
İkinci nesne de aynı yoldan kurulur (adet = 2). Dizinin öğe tipi soyut Sekil, gösterdikleri somut nesneler.
ozet() somut, Sekil’den gelir. İçindeki alan() soyut; this bir Kare → Kare.alan(): 4.0.
Aynı satır, farklı nesne: bu kez Daire.alan() = 3 · 1 · 1 = 3.0. Soyut sınıftaki kod, alt sınıfın yazdığı metodu çağırır.
static sayaç iki yapıcı çağrısını saydı: 2.
abstract class Sekil { static int adet = 0; String ad; Sekil(String ad) { this.ad = ad; adet++; } abstract double alan(); String ozet() { return ad + ":" + alan(); } } class Kare extends Sekil { double k; Kare(double k) { super("Kare"); this.k = k; } double alan() { return k * k; } } class Daire extends Sekil { double r; Daire(double r) { super("Daire"); this.r = r; } double alan() { return 3 * r * r; } } // main içinde: Sekil[] d = { new Kare(2), new Daire(1) }; for (Sekil s : d) System.out.println(s.ozet()); System.out.println(Sekil.adet);
Çıktı Sorusu · Soyut Sınıflar
Soru 5: Çay mı, Kahve mi?
Program ne yazar? Cay’da final hazirla() geçersiz kılınmak istense ne olur?
abstract class Icecek { final void hazirla() { System.out.print("su "); demle(); if (sut()) System.out.print("süt "); System.out.println("servis"); } abstract void demle(); boolean sut() { return false; } } class Cay extends Icecek { void demle() { System.out.print("çay "); } } class Kahve extends Icecek { void demle() { System.out.print("kahve "); } @Override boolean sut() { return true; } } // main: new Cay().hazirla(); // Icecek i = new Kahve(); i.hazirla();
Cevabı göster
su çay servis su kahve süt servis
- İskelet (sıra) soyut sınıfta, değişen adım alt sınıfta: şablon metot.
demle()her nesnede kendi sınıfının sürümüyle çalışır.sut()bir “kanca”dır: yalnızcaKahveonu geçersiz kılar.finalmetot geçersiz kılınamaz:hazirla() in Cay cannot override hazirla() in Icecek; overridden method is final. Alt sınıflar sırayı bozamaz.
Çoktan Seçmeli · Arayüzler
Soru 6: Arayüzde Alan
interface GeometrikSekil { int KENAR_SAYISI = 4; void ciz(); } için hangisi doğrudur?
A: Arayüzde alan olarak yalnızca sabit tanımlanır: örtük public static final. GeometrikSekil.KENAR_SAYISI = 5; → cannot assign a value to static final variable; değer vermemek → = expected. Gövdesiz metotlar örtük public abstract’tır (C).
Çoktan Seçmeli · Arayüzler
Soru 7: public Unutulursa
class Kare implements GeometrikSekil { void ciz() { } } yazıldı. Ne olur?
D: Arayüz metodu örtük public’tir; gerçekleştiren metot erişimi daraltamaz: ciz() in Kare cannot implement ciz() in GeometrikSekil; attempting to assign weaker access privileges; was public. Doğrusu public void ciz().
Adım Adım Çalıştırma · Arayüzler
Soru 8: Arayüz Tipinde Sepet
Üç ilgisiz sınıf aynı arayüzü gerçekleştiriyor. Döngü sonunda toplam ve en pahalı ürünün fiyatı nedir?
Dizinin öğe tipi bir arayüz; öğeler üç ilgisiz sınıfın nesnelerini gösterir. Ortak noktaları yalnızca Fiyatli sözleşmesi.
f → Kitap: Kitap.fiyat() = 40.0. 40 > 40 yanlış; en pahalı değişmez.
f → Kalem: 7.5 × 4 = 30.0; toplam 70.0. 30 > 40 yanlış.
f → Bilet: 25.0; toplam 95.0. Aynı çağrı, her turda başka bir sınıfın metodu (dinamik bağlama).
Çıktı: 95.0 40.0. Yeni bir Fiyatli sınıfı eklemek için döngü değişmez.
interface Fiyatli { double fiyat(); } class Kitap implements Fiyatli { public double fiyat() { return 40; } } class Kalem implements Fiyatli { int adet; Kalem(int adet) { this.adet = adet; } public double fiyat() { return 7.5 * adet; } } class Bilet implements Fiyatli { public double fiyat() { return 25; } } // main içinde: Fiyatli[] sepet = { new Kitap(), new Kalem(4), new Bilet() }; double toplam = 0; Fiyatli enPahali = sepet[0]; for (Fiyatli f : sepet) { toplam += f.fiyat(); if (f.fiyat() > enPahali.fiyat()) enPahali = f; } System.out.println(toplam + " " + enPahali.fiyat());
Adım Adım Çalıştırma · Arayüz Metotları
Soru 9: default Metot ve Geçersiz Kılma
ikiKez() arayüzde bir kez yazılmış. İki nesnede kaç artış yapar? Program ne yazar?
İki nesne, ikisi de Sayac tipinde referanslarla tutuluyor. Ciftli, d alanını Basit’ten alır (private, yalnızca metotlarla erişilir).
ikiKez() arayüzün default metodu; Basit yazmadığı için o çalışır. İçindeki arttir() = this.arttir() → Basit’in sürümü: d = 1.
İkinci çağrı: d = 2.
Aynı default metot, ama this bir Ciftli: geçersiz kılınmış arttir() iki kez super.arttir() yapar → d = 2.
İkinci arttir(): d = 4.
sifirMi() de default: deger() 4, sıfır değil. Çıktı: 2 4 false.
interface Sayac { int deger(); void arttir(); default boolean sifirMi() { return deger() == 0; } default void ikiKez() { arttir(); arttir(); } } class Basit implements Sayac { private int d; public int deger() { return d; } public void arttir() { d++; } } class Ciftli extends Basit { @Override public void arttir() { super.arttir(); super.arttir(); } } // main içinde: Sayac a = new Basit(); Sayac b = new Ciftli(); a.ikiKez(); b.ikiKez(); System.out.println(a.deger() + " " + b.deger() + " " + b.sifirMi());
Çoktan Seçmeli · Arayüz Metotları
Soru 10: Arayüzün static Metodu
interface Hesap { static int topla(int a, int b) { return a + b; } } ve class Basit implements Hesap { } var. Hesap.topla(3, 4) ile Basit.topla(3, 4) için hangisi doğrudur?
A: Arayüzün static metotları gerçekleştiren sınıfa kalıtımla geçmez; yalnızca arayüz adıyla çağrılır. Basit.topla → cannot find symbol. (Sınıflardaki static metotlar ise alt sınıf adıyla da çağrılabilir.)
Çıktı Sorusu · Arayüz Metotları
Soru 11: İki default selam()
İki arayüz aynı imzalı default metot getiriyor. Program ne yazar? Gorevli’de selam() hiç yazılmasaydı ne olurdu?
// p(s): System.out.println(s) interface Selamlayan { default void selam() { p("Merhaba"); } } interface Karsilayan { default void selam() { p("Hoş geldiniz"); } } class Gorevli implements Selamlayan, Karsilayan { public void selam() { Karsilayan.super.selam(); p("Ben Görevli"); } } // main içinde: Selamlayan s = new Gorevli(); s.selam();
Cevabı göster
Hoş geldiniz Ben Görevli
- Referans
Selamlayantipinde olsa da nesneGorevli: onunselam()’ı çalışır. Karsilayan.super.selam()yalnızca o arayüzündefaultsürümünü çağırır;Merhabahiç yazılmaz.selam()yazılmasaydı derlenmezdi:class Gorevli inherits unrelated defaults for selam() from types Selamlayan and Karsilayan.
Çoktan Seçmeli · Arayüz Metotları
Soru 12: private Arayüz Metodu
Java 9+ arayüzündeki private String baslik() { return "Belge"; } metodunu kimler çağırabilir?
C: private arayüz metotları, default ve static metotların ortak yardımcı kodunu dışarı açmadan paylaşmak içindir. Gerçekleştiren Rapor sınıfı baslik()’ı çağıramaz: cannot find symbol.
Çoktan Seçmeli · Mühürlü Tipler
Soru 13: Mühürlü Hiyerarşi
sealed abstract class Sekil permits Kare, Cember; final class Kare extends Sekil; non-sealed class Cember extends Sekil. Hangisi doğrudur? (Java 17+)
B: non-sealed kısıtı kaldırır, Cember’i herkes genişletebilir. Ucgen permits listesinde yok: class is not allowed to extend sealed class: Sekil.
Hata Bulma · Mühürlü Tipler
Soru 14: Belirleyicisi Eksik Alt Tip
Kod derlenmiyor (Java 17+). Hata hangi satırda, nedir? Üç farklı düzeltme yazın; her birinin anlamı nedir?
sealed interface Hayvan permits Kedi, Kopek { } class Kedi implements Hayvan { } final class Kopek implements Hayvan { }
Cevabı göster
error: sealed, non-sealed or final
modifiers expected
class Kedi implements Hayvan { }permits listesindeki her alt tip birini seçmek zorundadır:
final class Kedi: hiyerarşi burada biter.sealed class Kedi permits Tekir: yeniden kısıtlar (Tekirde birini seçmelidir).non-sealed class Kedi: herkes genişletebilir.
Çoktan Seçmeli · Karşılaştırma
Soru 15: Yalnızca Soyut Sınıfta
Aşağıdakilerden hangisi soyut sınıfta yapılabilir ama arayüzde yapılamaz?
D: Arayüzün nesnesi ve durumu yoktur: örnek alanı ve yapıcı tanımlanamaz. Gövdeli metot arayüzde de olur (default, static, private); sabitler ikisinde de tanımlanır; bir sınıfın birden çok tipi birlikte alması (B) ise yalnızca arayüzlerle mümkündür.
Kod Yazma · Karşılaştırma
Soru 16: Taşıt ve Şarj
Plakası ve yapıcısı olan, soyut int tekerSayisi() metodu bulunan Tasit; KAPASITE = 100 sabiti ve void sarjEt(int yuzde) metodu olan Sarj. Hangisi soyut sınıf, hangisi arayüz olmalı? İkisini birlikte kullanan, doluluğu %20’den başlayıp kapasiteyi aşmayan ElektrikliAraba’yı yazın. İki kez sarjEt(50) sonrası doluluk kaçtır?
Cevabı göster
Tasit: ortak alan + yapıcı → soyut sınıf. Sarj: ilgisiz sınıflara da verilebilecek yetenek → arayüz.
class ElektrikliAraba extends Tasit implements Sarj {
private int doluluk = 20;
ElektrikliAraba(String plaka) { super(plaka); }
int tekerSayisi() { return 4; }
public void sarjEt(int yuzde) {
doluluk = Math.min(KAPASITE, doluluk + yuzde);
}
int getDoluluk() { return doluluk; }
}20 → 70 → 100 (120 değil): 100. Önce extends, sonra implements; sarjEt public olmalı. Nesne hem Tasit hem Sarj tipindeki referansa atanabilir.