Bölüm 4: Soyut Sınıflar ve Arayüzler
Giriş
Öğrenme Çıktıları
abstract sınıf ve metot tanımlamak; soyut sınıftan neden nesne oluşturulamadığını ve alt sınıfın neyi gerçeklemek zorunda olduğunu açıklamak.
Soyut türden bir referansla çağrılan metodun, çalışma anında nesnenin gerçek sınıfından seçildiğini kodu izleyerek göstermek.
interface tanımlamak, implements ile bir ya da birden çok arayüzü gerçeklemek; default, static ve private metotları kullanmak.
Mühürlü (sealed) türleri tanımak; bir problem için arayüz mü soyut sınıf mı (ya da ikisi birden) gerektiğine karar vermek.
Soyutlama
Soyutlama (Abstraction)
- Soyutlama: karmaşık ayrıntıları gizleyip yalnızca temel özellikleri göstermek.
- Araba kullanan kişi direksiyonu ve pedalları bilir; motorun içini bilmek zorunda değildir.
- “Şekil” bir kavramdır: her şeklin alanı vardır, ama genel bir şeklin alanı hesaplanamaz. Formülü yalnızca Kare, Çember, Üçgen bilir.
- Java'da soyutlamanın iki aracı vardır: soyut sınıflar (
abstract class) ve arayüzler (interface). - İkisi de ne yapılacağını söyler; nasıl yapılacağını alt sınıflara bırakır.
Ortak kavram yukarıda, ayrıntı aşağıda.
Soyut Sınıflar
Soyut Sınıf (Abstract Class)
abstractanahtar kelimesiyle tanımlanır:public abstract class Sekil.- Hem soyut (gövdesiz) hem de somut (concrete, gövdeli) metotlar içerebilir.
public abstract class Sekil { // Soyut olmayan (somut) metot void tasi(int x, int y) { System.out.println("(" + x + ", " + y + ") noktasına taşındı"); } // Soyut metot (alt sınıflarca gerçeklenmeli) abstract void ciz(); }
tasiGövdesi hazırdır. Alt sınıflar onu olduğu gibi miras alır; isterse geçersiz kılar (override).
cizYalnızca imzası vardır. Her somut alt sınıf kendi ciz() gövdesini yazmak zorundadır.
Soyut sınıf yarım kalmış bir plan gibidir: bazı odalar bitmiş, bazılarının yalnızca yeri belli.
Soyut Sınıflar
Soyut Sınıfın Özellikleri
- Soyut sınıftan nesne oluşturulamaz (örneği, instance'ı olamaz).
- Başka sınıflar onu
extendsile genişletir (kalıtım). - Somut bir alt sınıf, tüm soyut metotları gerçeklemek (implement) zorundadır.
- Ortak durumu (alanlar) ve davranışları tek yerde toplar → kod yeniden kullanılır.
- Alt sınıflar soyut metotları kendi ihtiyacına göre doldurur.
- Yapıcı metotları (constructor) olabilir; alt sınıf onları
super(...)ile çağırır.
UML'de soyut sınıf ve soyut metot eğik yazılır.
Soyut Sınıflar
Soyut Sınıftan Nesne Oluşturulamaz
Sekil s1 = new Sekil("?"); // HATA Sekil s2 = new Kare(3); // Doğru: değişkenin türü soyut olabilir Sekil[] dizi = new Sekil[3]; // Doğru: dizi yalnızca referans tutar
Derleyici mesajı (1. satır)
error: Sekil is abstract; cannot be instantiated
Sekil'in alan() metodunun gövdesi yok. new Sekil() olsaydı s1.alan() çağrısında çalıştırılacak kod bulunmazdı.
Değişken, parametre, dizi elemanı ve dönüş türü Sekil olabilir. new Sekil[3] nesne değil, 3 boş (null) referans oluşturur.
abstract final class yazılamaz: final genişletmeyi yasaklar, abstract genişletmeyi gerektirir → illegal combination of modifiers: abstract and final.
Soyut Sınıflar
Soyut Metotlar (Abstract Methods)
- Gerçekleştirim (implementasyon) olmadan tanımlanır.
- Süslü parantez içermez, noktalı virgülle biter:
public abstract void ciz();
- Soyut metodu olan sınıf soyut olmak zorundadır.
- Soyut sınıflar genellikle kalıtım hiyerarşisinin tepesinde yer alır.
public abstract class Sekil { // Soyut metot public abstract void ciz(); } // Ayrı bir dosyada: public class Cember extends Sekil { // ciz metodunu gerçeklemek zorunlu public void ciz() { System.out.println("Çember çiziliyor"); } }
new Cember().ciz(); çıktısı
Çember çiziliyor
Soyut Sınıflar
Soyut Metot Kuralları
| Yazılan | Sonuç |
|---|---|
abstract void ciz(); (soyut sınıfta) | ✓ Doğru |
abstract void ciz() { } | abstract methods cannot have a body |
class Sekil { abstract void ciz(); } | Sekil is not abstract and does not override abstract method ciz() in Sekil |
class Cember extends Sekil { } (ciz yok) | Cember is not abstract and does not override abstract method ciz() in Sekil |
private abstract, static abstract, final abstract | illegal combination of modifiers: abstract and private (static, final için de aynı) |
abstract class Cember extends Sekil { } | ✓ Doğru: soyut alt sınıf, gerçeklemeyi kendi alt sınıflarına bırakabilir |
abstract class A { void f() { } } | ✓ Doğru: hiç soyut metodu olmayan soyut sınıf da yazılabilir (yine de new A() yapılamaz) |
Neden private/static/final olmaz? Üçü de metodun alt sınıfta geçersiz kılınmasını engeller; soyut metot ise geçersiz kılınmak için vardır.
Soyut Sınıflar · Kodu adım adım çalıştır
new Kare(3): Yapıcı Zinciri
new Kare(3): önce öbekte (heap) bir Kare nesnesi ayrılır. Alanlar varsayılan değer alır: null ve 0.0.
Kare'nin yapıcısı çalışır. Parametre kenar = 3.0 (int 3, double'a genişletildi).
İlk iş super("Kare"): üst sınıfın yapıcısı çağrılır. Soyut sınıfın da yapıcısı olabilir.
Sekil yapıcısı çalışıyor. Ayrı bir Sekil nesnesi oluşmaz: aynı nesnenin Sekil'den gelen kısmı kuruluyor.
this.isim = isim: nesnenin isim alanı "Kare" olur.
Mesaj yazdırılır. Sekil yapıcısı biter, çerçevesi yığından çıkar.
Kare yapıcısına dönülür: this.kenar = 3.0. Nesne artık tamamen kurulmuştur.
Nesnenin referansı s'ye atanır. Değişkenin türü Sekil (soyut), gösterdiği nesne Kare.
s.alan(): Sekil'de alan() soyut. Çalışma anında nesnenin türüne bakılır → Kare.alan(): 3.0 · 3.0.
Dönen 9.0 yazdırılır.
abstract class Sekil { private String isim; Sekil(String isim) { this.isim = isim; System.out.println(isim + " kuruldu"); } abstract double alan(); } class Kare extends Sekil { private double kenar; Kare(double kenar) { super("Kare"); this.kenar = kenar; } double alan() { return kenar * kenar; } } // main içinde: Sekil s = new Kare(3); System.out.println(s.alan());
Soyut Sınıflar · Kodu adım adım çalıştır
Soyut Türde Dizi: Dinamik Bağlama
Dizi iki referans tutar. Elemanların türü Sekil, gösterdikleri nesneler Kare ve Cember.
1. tur: t, dizi[0]'daki Kare nesnesini gösterir.
t.alan(): derleyici yalnızca Sekil'de alan() olduğunu bilir; JVM nesneye bakar → Kare.alan(): 2.0 · 2.0.
Dönen 4.0 yazdırılır.
Kare ciz()'i geçersiz kılmadı (override etmedi) → Sekil'deki somut ciz() miras olarak çalışır.
2. tur: t artık Cember nesnesini gösterir. Aynı satır, farklı nesne.
Bu kez Cember.alan() seçilir: π · 1.0 · 1.0.
Dönen değer yazdırılır: Math.PI.
Cember ciz()'i geçersiz kılmış → kendi sürümü: dinamik bağlama (dynamic binding).
Eleman kalmadı, döngü biter. Yeni bir şekil (ör. Ucgen) eklemek için bu döngüyü değiştirmek gerekmez.
abstract class Sekil { // isim alanı ve yapıcısı abstract double alan(); void ciz() { System.out.println(isim + " çiziliyor"); } } class Kare extends Sekil { // kenar alanı ve yapıcısı double alan() { return kenar * kenar; } } class Cember extends Sekil { // r alanı ve yapıcısı double alan() { return Math.PI * r * r; } void ciz() { System.out.println("Çember, r = " + r); } } // main içinde: Sekil[] dizi = { new Kare(2), new Cember(1) }; for (Sekil t : dizi) { System.out.println(t.alan()); t.ciz(); }
Soyut Sınıflar · Kodu adım adım çalıştır
Somut Metot Soyut Metodu Çağırır
Değişken türü Icecek (soyut), nesne Cay. Cay tek soyut metodu demle()'yi gerçeklediği için somuttur.
Cay'da hazirla() yok → Icecek'ten miras alınan somut metot çalışır. final: alt sınıflar bu sırayı değiştiremez.
1. adım: suyuKaynat(), yani this.suyuKaynat() çağrılır.
Icecek'teki somut suyuKaynat() çalışır.
2. adım: demle(). Icecek'te gövdesi yok, ama this bir Cay nesnesi…
…bu yüzden Cay.demle() çalışır. Soyut sınıftaki kod, henüz yazılmamış alt sınıf kodunu çağırabilir.
3. adım: servis mesajı yazdırılır.
İskelet soyut sınıfta, değişen adım alt sınıfta: şablon metot (template method). Bir Kahve sınıfı yalnızca demle()'yi yazar.
abstract class Icecek { final void hazirla() { suyuKaynat(); demle(); System.out.println("Servis edildi"); } void suyuKaynat() { System.out.println("Su kaynadı"); } abstract void demle(); } class Cay extends Icecek { void demle() { System.out.println("Çay demlendi"); } } // main içinde: Icecek i = new Cay(); i.hazirla();
Arayüzler
Arayüz (Interface) Nedir?
- Bir sistemin belirli işlevlere sahip olacağını garanti eden sözleşmedir (contract).
- İki sistem arasındaki entegrasyon noktasını temsil eder: kullanan taraf yalnızca arayüzü bilir.
interfaceanahtar kelimesiyle tanımlanır.- Arayüzdeki metotlar,
publicyazılsın ya da yazılmasın public'tir. static,defaultya daprivatedeğilse metot otomatik olarak abstract'tır.- Alan olarak yalnızca
public static finalsabitler içerebilir.
Priz bir sözleşmedir: hangi cihaz takılırsa takılsın aynı gerilimi verir. Ütü de bilgisayar da prizin standardına uyar; şebeke cihazın içini, cihaz şebekenin içini bilmez.
Arayüzler
Arayüz Tanımlama
Yazdığımız
public interface GeometrikSekil { // Soyut metot (public abstract) void ciz(); // Sabit (public static final) int KENAR_SAYISI = 4; }
Derleyicinin gördüğü
public interface GeometrikSekil { public abstract void ciz(); public static final int KENAR_SAYISI = 4; }
- Sabitlere arayüz adıyla erişilir:
GeometrikSekil.KENAR_SAYISI→4. Adları BÜYÜK_HARF ile yazılır. - Sabite değer vermek zorunludur:
int deger;→error: = expected. - Sabit değiştirilemez:
GeometrikSekil.KENAR_SAYISI = 5;→error: cannot assign a value to static final variable KENAR_SAYISI. - Arayüzden de nesne oluşturulamaz:
new GeometrikSekil()→error: GeometrikSekil is abstract; cannot be instantiated.
Arayüzler
Arayüz Gerçekleme (implements)
- Bir sınıf, bir arayüzü
implementsanahtar kelimesiyle gerçekler. - Arayüzdeki tüm soyut metotları gerçeklemeli ya da kendisi
abstractolmalıdır. - Eksik metot:
Kare is not abstract and does not override abstract method ciz() in GeometrikSekil. - Gerçekleyen metot
publicolmalıdır.void ciz()yazılırsa:attempting to assign weaker access privileges; was public. - Arayüz türünde değişken, onu gerçekleyen her sınıfın nesnesini gösterebilir.
public class Kare implements GeometrikSekil { // ciz metodunu gerçeklemek zorunlu public void ciz() { System.out.println("Kare çiziliyor"); } } // main içinde: GeometrikSekil g = new Kare(); g.ciz(); System.out.println(GeometrikSekil.KENAR_SAYISI);
Çıktı
Kare çiziliyor 4
Arayüzler
Bir Sınıf, Birden Fazla Arayüz
- Bir sınıf en fazla bir üst sınıfı genişletebilir (
extends)… - …ama sıfır ya da daha çok arayüzü gerçekleyebilir (
implements A, B, …). - Önce
extends, sonraimplementsyazılır. class C extends A, B→error: '{' expected.
class Hayvan { String isim; Hayvan(String isim) { this.isim = isim; } } interface Ucabilir { void uc(); } interface Yuzebilir { void yuz(); } class Ordek extends Hayvan implements Ucabilir, Yuzebilir { Ordek(String isim) { super(isim); } public void uc() { System.out.println(isim + " uçuyor"); } public void yuz() { System.out.println(isim + " yüzüyor"); } }
Arayüzler · Kodu adım adım çalıştır
Aynı Nesne, Farklı Arayüz Referansları
Öbekte tek bir Ordek nesnesi oluşur; o onu gösterir.
Atama nesneyi kopyalamaz: u aynı nesneyi gösterir. Ordek bir Ucabilir'dir → dönüşüm otomatik.
y da aynı nesneyi gösterir. Bir nesne, üç farklı türden “bakış”.
u.uc(): u'nun türü Ucabilir; ondan yalnızca uc() çağrılabilir. Çalışan, nesnenin kendi uc()'su.
y.yuz(): Yuzebilir türü yuz()'ü bilir.
u.yuz() yazılsaydı: error: cannot find symbol. Nesnede yuz() var, ama derleyici referansın türüne bakar.
o'nun türü Ordek: alan isim dahil her şey erişilebilir.
== referansları karşılaştırır: hepsi aynı nesneyi gösterir → true.
Ordek o = new Ordek("Donald"); Ucabilir u = o; Yuzebilir y = o; u.uc(); y.yuz(); // u.yuz(); derleme hatası! System.out.println(o.isim); System.out.println(u == o);
Arayüzler
Arayüzden Kalıtım
Bir arayüz, başka bir arayüzü extends ile genişletebilir; virgülle birden çok arayüzü de genişletebilir: interface C extends A, B.
public interface KareSekli extends GeometrikSekil { // Ek metotlar veya sabitler eklenebilir void ozelFonksiyon(); } class OzelKare implements KareSekli { public void ciz() { System.out.println("Özel kare çiziliyor"); } public void ozelFonksiyon() { System.out.println("Köşegen: " + Math.sqrt(2)); } } // main içinde: KareSekli k = new OzelKare(); k.ciz(); k.ozelFonksiyon(); GeometrikSekil g = k; // üst arayüze atanabilir
Çıktı
Özel kare çiziliyor Köşegen: 1.4142135623730951
Arayüz Metotları
Varsayılan Metotlar (default, Java 8+)
- Arayüz, gövdesi olan varsayılan (
default) metotlara sahip olabilir. - Gerçekleyen sınıf onu miras alır; isterse geçersiz kılar. Amaç: arayüze yeni metot eklerken onu gerçekleyen eski sınıfları bozmamak.
interface Collection { void add(Object o); void remove(Object o); int size(); default boolean isEmpty() { return size() == 0; } }
Çıktı
true 2 false
class Sepet implements Collection { private int adet = 0; public void add(Object o) { adet++; } public void remove(Object o) { adet--; } public int size() { return adet; } // isEmpty() yazılmadı: default sürüm kullanılır } // main içinde: Sepet sepet = new Sepet(); System.out.println(sepet.isEmpty()); sepet.add("elma"); sepet.add("armut"); System.out.println(sepet.size() + " " + sepet.isEmpty());
isEmpty(), soyut size()'ı çağırır; hangi size()'ın çalışacağı nesneye göre belirlenir. (Bu Collection bizim arayüzümüzdür; java.util.Collection Bölüm 5'te.)
Arayüz Metotları
Statik Metotlar (static, Java 8+)
interface Geometry { static double circleArea(double r) { return Math.PI * r * r; } static double squareArea(double s) { return s * s; } static double perimeter(double s) { return s * 4.0; } static double boxVolume(double w, double h, double d) { return w * h * d; } } // main içinde: System.out.println(Geometry.circleArea(2)); System.out.println(Geometry.squareArea(3)); System.out.println(Geometry.perimeter(2.5)); System.out.println(Geometry.boxVolume(2, 3, 4));
Çıktı
12.566370614359172 9.0 10.0 24.0
- Nesneye bağlı olmayan yardımcı işlevler; yalnızca arayüz adıyla çağrılır:
Geometry.circleArea(2). - Gerçekleyen sınıfa miras geçmez:
Daire implements Geometryolsa daDaire.squareArea(2)→cannot find symbol. - Yalnız
PIyazılırsacannot find symbol; sabitMathsınıfındadır:Math.PI.
Arayüz Metotları
Default Metot Çakışması
- İki arayüz aynı imzalı default metot getirirse sınıf hangisini alacağını bilemez; metodu kendisi yazmak (geçersiz kılmak) zorundadır.
- İstenen arayüzün sürümü
ArayuzAdi.super.metot()ile çağrılabilir.
interface Selamlayan { default void selam() { System.out.println("Merhaba"); } } interface Karsilayan { default void selam() { System.out.println("Hoş geldiniz"); } } class Gorevli implements Selamlayan, Karsilayan { public void selam() { // geçersiz kılmak zorunlu Selamlayan.super.selam(); Karsilayan.super.selam(); } }
new Gorevli().selam();
Merhaba Hoş geldiniz
selam() yazılmasaydı
error: types Selamlayan and Karsilayan are incompatible; class Gorevli inherits unrelated defaults for selam() from types Selamlayan and Karsilayan
Arayüz Metotları
Özel (private) Arayüz Metotları (Java 9+)
interface Yazdirilabilir { String icerik(); default void yazdir() { System.out.println(baslik() + ": " + icerik()); } private String baslik() { // Java 9+ return "Belge"; } } class Rapor implements Yazdirilabilir { public String icerik() { return "Vize sonuçları"; } }
new Rapor().yazdir();
Belge: Vize sonuçları
privatemetotlar, default (ve static) metotların ortak yardımcı kodunu dışarı açmadan paylaşır.- Gövdeleri vardır ve yalnızca arayüzün içinden çağrılabilir.
- Gerçekleyen sınıf onları göremez:
Raporiçindebaslik()çağrılamaz. - Akış:
yazdir()(default) →baslik()(private) +icerik()(Rapor'un gerçeklediği soyut metot).
Arayüz Metotları
Arayüz Üyeleri: Özet Tablosu
| Üye | Örnek | Örtük belirteçler | Gövde | Java |
|---|---|---|---|---|
| Soyut metot | void ciz(); | public abstract | yok | 1.0 |
| Sabit | int KENAR_SAYISI = 4; | public static final | — | 1.0 |
| Varsayılan metot | default boolean isEmpty() {…} | public | var | 8 |
| Statik metot | static double squareArea(…) {…} | public | var | 8 |
| Özel metot | private String baslik() {…} | yalnızca arayüz içinde | var | 9 |
| Örnek alanı, yapıcı | — | İzin verilmez: arayüzün nesnesi yoktur, durum (state) tutamaz | ||
public olarak yazmak. Default metotlar isteğe bağlı, static ve private metotlar zaten miras geçmez.Mühürlü Türler
Mühürleme: sealed, non-sealed, permits
- Sınıflar ve arayüzler mühürlenebilir (Java 17+).
sealed: türü yalnızca izin verilen alt türler genişletebilir ya da gerçekleyebilir.permits: izin verilen alt türlerin listesi.- İzin verilen her alt tür birini seçmek zorundadır:
final: hiyerarşi burada biter;sealed: yeniden kısıtlar;non-sealed: kısıtı kaldırır, herkes genişletebilir. - Yarar: derleyici tüm alt türleri bilir (kapalı hiyerarşi).
Mühürlü Türler
Mühürlü Arayüz Örneği
public sealed interface Hayvan permits Kedi, Kopek { void hareketEt(); } final class Kedi implements Hayvan { public void hareketEt() { System.out.println("Kedi sessizce yürüyor"); } } non-sealed class Kopek implements Hayvan { public void hareketEt() { System.out.println("Köpek koşuyor"); } } class Kangal extends Kopek { // serbest public void hareketEt() { System.out.println("Kangal sürüyü koruyor"); } }
// Java 21: switch tüm alt türleri kapsar, // default dalı gerekmez static String tur(Hayvan h) { return switch (h) { case Kedi k -> "kedi"; case Kopek k -> "köpek"; }; } // main içinde: Hayvan[] hayvanlar = { new Kedi(), new Kopek(), new Kangal() }; for (Hayvan h : hayvanlar) { h.hareketEt(); System.out.println(tur(h)); }
Çıktı
Kedi sessizce yürüyor kedi Köpek koşuyor köpek Kangal sürüyü koruyor köpek
Karşılaştırma
Arayüz ve Soyut Sınıf Karşılaştırması
| Özellik | Arayüz | Soyut sınıf |
|---|---|---|
| Tanım / kullanım | interface · implements | abstract class · extends |
| Metotlar | Soyut; Java 8+ default ve static, Java 9+ private | Hem soyut hem somut metotlar |
| Alanlar | Yalnızca public static final sabitler; örnek alanı (instance field) olamaz | Her türlü alan (örnek alanları dahil) |
| Yapıcı | Yok | Olabilir; alt sınıf super(…) ile çağırır |
| Erişim | Üyeler örtük public (private yardımcılar hariç) | public, protected, private, paket |
| Kalıtım | Bir sınıf çok sayıda arayüz gerçekler; arayüz birden çok arayüzü genişletir → çoklu kalıtım özelliği | Bir sınıf yalnızca tek bir sınıftan türetilir |
| Amaç | İlgisiz sınıflara ortak yetenek (“yapabilir”) | Ortak niteliklere sahip sınıfları gruplamak (“bir türüdür”) |
| Nesne | İkisinden de new ile nesne oluşturulamaz; ikisi de referans türü olarak kullanılır | |
Karşılaştırma
Hangisini Seçmeli?
Soyut sınıf seçin
- Alt sınıflar yakın akraba: Kare, Çember birer Sekil'dir.
- Ortak alanlar ve yapıcı gerekiyor (
isim). - Ortak kodun bir kısmı hazır (şablon metot).
Arayüz seçin
- İlgisiz sınıflara aynı yetenek: Kus, Ucak, Drone hepsi Ucabilir.
- Bir sınıfa birden çok yetenek kazandırmak.
- Kullanan kodla gerçekleyen kod arasında sözleşme (API).
Çoğu zaman ikisi birlikte kullanılır:
abstract class Hayvan implements Sesli { … } class Ordek extends Hayvan implements Ucabilir, Yuzebilir { … }
Özet
Özet
| Kavram | Özü |
|---|---|
| Soyutlama | Ayrıntıyı gizleyip “ne yapılır”ı tanımlamak; “nasıl”ı alt sınıflara bırakmak |
| Soyut sınıf | abstract class; nesnesi olmaz; alan, yapıcı, soyut ve somut metot içerebilir |
| Soyut metot | Gövdesiz, ; ile biter; somut alt sınıf gerçeklemek zorunda |
| Dinamik bağlama | Derleyici referans türüne, JVM nesnenin gerçek türüne bakar |
| Arayüz | Sözleşme; metotlar örtük public abstract, alanlar public static final |
| implements | Tek extends, çok sayıda implements; gerçekleyen metot public |
| default / static / private | Gövdeli arayüz metotları (Java 8 / 8 / 9) |
| sealed | permits ile izinli alt türler; her biri final, sealed ya da non-sealed |
Özet
İlgili Sayfalar
Arayüzler, çoklu gerçekleme, default, static ve private metotlar; ödeme sistemi örneği (İngilizce).
Genel (generic) sınıflar ve metotlar, sınırlı tür parametreleri, joker türler (İngilizce).
@Override gibi açıklamalar (annotation), özel açıklamalar ve yansıma (reflection) (İngilizce).
@Override yazın. Adı ya da parametreyi yanlış yazarsanız derleyici hemen uyarır.Özet
Sık Yapılan Hatalar (1): Soyut Sınıflar
new Sekil("?") → Sekil is abstract; cannot be instantiated. Somut bir alt sınıf kullanın.
Cember is not abstract and does not override abstract method ciz() in Sekil. Metodu yazın ya da sınıfı abstract yapın.
abstract void ciz() { } → abstract methods cannot have a body. Ya abstract ya da gövde.
class Sekil { abstract void ciz(); } → Sekil is not abstract and does not override abstract method ciz() in Sekil.
abstract final, private abstract, static abstract → illegal combination of modifiers.
double Alan() ya da double alan(int x) yeni bir metottur, soyut alan() hâlâ eksiktir. @Override bunu yakalar.
Özet
Sık Yapılan Hatalar (2): Arayüzler
public'i unutmakvoid ciz() { … } → attempting to assign weaker access privileges; was public. Arayüz metodunu public yazın.
GeometrikSekil.KENAR_SAYISI = 5; → cannot assign a value to static final variable KENAR_SAYISI.
class C extends A, B → '{' expected. Tek extends, çok sayıda implements.
Ucabilir u = new Ordek(); u.yuz(); → cannot find symbol. Uygun türde referans kullanın.
class Gorevli inherits unrelated defaults for selam(). Metodu sınıfta geçersiz kılın.
İzinsiz alt tür: class is not allowed to extend sealed class: Hayvan. İzinli alt türde belirteç yok: sealed, non-sealed or final modifiers expected.
Özet
Örnek Problemler (1): Derlenir mi?
// (a) abstract class A { void f() { System.out.println("f"); } } // (b) class B { abstract void g(); } // (c) interface I { int X = 1; } ... I.X++; // (d) interface J { void h(); } class C implements J { void h() { } } // (e) abstract class D { abstract void k(); } abstract class E extends D { }
- Her parça (a)–(e) için: derlenir mi? Derlenmiyorsa hata nedir?
- Derlenen parçalardan hangisinin nesnesi
newile oluşturulabilir?
Cevapları göster
- (a) Derlenir: soyut metodu olmayan soyut sınıf geçerlidir. (b) Hata:
B is not abstract and does not override abstract method g() in B. (c) Hata:cannot assign a value to static final variable X. (d) Hata:h()publicdeğil →weaker access privileges; was public. (e) Derlenir: E de soyut olduğu içink()'yı yazmak zorunda değil. - Hiçbiri: A ve E soyut olduğundan
new A(),new E()da derleme hatasıdır.
Özet
Örnek Problemler (2): Çıktı Nedir?
interface Sesli { default String ses() { return "..."; } } abstract class Hayvan implements Sesli { Hayvan() { System.out.print("H "); } abstract String ad(); } class Kedi extends Hayvan { Kedi() { System.out.print("K "); } String ad() { return "kedi"; } public String ses() { return "miyav"; } } class Balik extends Hayvan { String ad() { return "balık"; } } // main içinde: Hayvan[] d = { new Kedi(), new Balik() }; System.out.println(); for (Hayvan h : d) System.out.println(h.ad() + ": " + h.ses());
- Program ne yazdırır?
Balik,ses()'i yazmadığı hâlde neden derlenir?Kedi'dekises()'tenpublicsilinirse ne olur?Sesli s = new Balik(); s.ad();derlenir mi?
Cevapları göster
H K H, sonrakedi: miyavvebalık: .... Kedi oluşurken önce Hayvan yapıcısı (H), sonra Kedi yapıcısı (K); Balik'te yalnızca H.ses()soyut değil,default: Balik onu miras alır; tek soyut metotad()'ı yazmıştır.- Derleme hatası:
weaker access privileges; was public. - Hayır:
cannot find symbol.Seslitürü yalnızcases()'i bilir.
Özet
Alıştırmalar (1)
- Soyut
Calisansınıfı yazın:isimalanı, yapıcı, soyutdouble maas()ve adı ile maaşı yazdıranbilgi(). Alt sınıflar:TamZamanli(aylık 30000),SaatUcretli(120 saat × 200). BirCalisan[]dizisindebilgi()çağırın. Sekil2Barayüzü: soyutdouble alan()ve"Alan: " + alan()döndüren defaultozet().Ucgen(6, 4)içinozet()ne döndürür?interface Hesap { static int topla(int a, int b) … }veclass Basit implements Hesap {}:Hesap.topla(3, 4)veBasit.topla(3, 4)sonuçları?
Cevaplar / ipuçları
double maas() { return saat * ucret; }gibi; çıktıAyşe: 30000.0/Ali: 24000.0.public double alan() { return taban * yukseklik / 2; }→Alan: 12.0.7; ikincisi derlenmez:cannot find symbol(statik arayüz metotları miras geçmez).
Özet
Alıştırmalar (2)
sealed abstract class Sekil permits Kare, Cemberyazın; Karefinal, Cembernon-sealed.Elips extends CemberveUcgen extends Sekilderlenir mi?- Soyut sınıf mı, arayüz mü? (a) plakası ve yapıcısı olan
Tasit; (b)OgrenciveFatura'nın ortakkaydet()yeteneği; (c) hem Hayvan hem yüzebilenBalik. class Kare implements GeometrikSekiliçindepublic void Ciz() { … }yazıldı. Ne olur? Metodun üstüne@Overrideeklenirse?
Cevaplar / ipuçları
Elipsderlenir (Cembernon-sealed);Ucgen:class is not allowed to extend sealed class: Sekil.- (a) soyut sınıf (ortak alan + yapıcı); (b) arayüz (ilgisiz sınıflar); (c)
class Balik extends Hayvan implements Yuzebilir. Ciz≠ciz(büyük/küçük harf):Kare is not abstract and does not override abstract method ciz() in GeometrikSekil.@Overrideile ek olarakmethod does not override or implement a method from a supertype.
Özet
Kaynaklar
- Oracle, The Java Tutorials: Abstract Methods and Classes; Interfaces; Default Methods.
- J. Gosling ve diğ., The Java Language Specification, Java SE 21 Edition (8.1.1.1 abstract Classes, 8.1.1.2 sealed Classes, Bölüm 9: Interfaces).
- Oracle, JEP 409: Sealed Classes (Java 17) ve JEP 441: Pattern Matching for switch (Java 21).
- P. Deitel ve H. Deitel, Java: How to Program, 11. baskı, Pearson (Bölüm 10: Object-Oriented Programming: Polymorphism and Interfaces).
- K. Sierra ve B. Bates, Head First Java, 3. baskı, O'Reilly (Bölüm 8: Interfaces and Abstract Classes).
- C. S. Horstmann, Core Java, Volume I: Fundamentals, 12. baskı, Pearson (Bölüm 5–6).