Neler yeni

Foruma hoş geldin 👋, Ziyaretçi

Forum içeriğine ve tüm hizmetlerimize erişim sağlamak için foruma kayıt olmalı ya da giriş yapmalısınız. Foruma üye olmak tamamen ücretsizdir.

  • Merhaba Değerli Ziyaretçimiz, ForumaGel ailesi seni bekliyor! 🌟 Aramıza katılarak güçlü ve samimi topluluğumuzun bir parçası olabilirsin. Burada her üye değerli, her katkı kıymetli. Şimdi üye ol, bizimle birlikte gelişmenin ve keyifli sohbetlerin tadını çıkar! Sevgi ve Saygılarla, ForumaGel Yönetimi ❤️
Yan Yana Banner
Yan Yana Banner
Katılım
7 Nis 2025
Konular
367
Mesajlar
780
Çözümler
1
Tepkime puanı
121
Puan
93
Konum
İstanbul
Web sitesi
forumagel.com
Hazır Kod Bankası - Konu 18: Java'da OOP - İleri Kavramlar



Hazır Kod Bankası Serimizin On Sekizinci Konusu: Java'da OOP'nin İleri Kavramları![/B]

Merhaba arkadaşlar! Java'da Nesne Tabanlı Programlamanın (OOP) temellerini gördük (Sınıf, Nesne, Özellik, Metot, Kurucu Metot). Artık Java'nın tamamen nesne tabanlı yapısının ne anlama geldiğini daha iyi anlıyoruz. OOP'yi güçlü, esnek ve bakımı kolay yazılımlar geliştirmek için kullanılan bir yaklaşım haline getiren dört ana prensip vardır: Miras Alma, Çok Biçimlilik, Kapsülleme ve Soyutlama.

Bu konuda, OOP'nin bu dört temel prensibini Java'nın sözdizimi ve kuralları içinde detaylı örneklerle inceleyeceğiz. Miras Alma ve Çok Biçimlilik kavramlarına Python üzerinden genel bir bakış atmıştık (Konu 12), şimdi bunları Java'daki somut uygulamalarıyla pekiştireceğiz ve Kapsülleme ile Soyutlama'ya giriş yapacağız.

1. Miras Alma (Inheritance) Java'da

Miras alma, bir sınıfın (alt sınıf veya türetilmiş sınıf), başka bir sınıftan (ana sınıf veya temel sınıf) özelliklerini ve metotlarını devralmasıdır. Bu, "bir ... türüdür" ("Is-a") ilişkisini kurar ve kod tekrarını önleyerek yeniden kullanılabilirliği artırır.

Java'da Sözdizimi: `extends` anahtar kelimesi kullanılır. Java'da tekli miras vardır, yani bir sınıf sadece tek bir sınıftan miras alabilir.

Java:
// Ana Sınıf (Base Class / Parent Class) - Hayvan.java
public class Hayvan {
    String isim;

    public Hayvan(String isim) {
        this.isim = isim;
    }

    public void sesCikar() { // Metot tanımlama
        System.out.println("Bir hayvan sesi");
    }

    public void yemekYe() {
        System.out.println(this.isim + " yemek yiyor.");
    }
}

// Alt Sınıf (Derived Class / Child Class) - Hayvan sınıfından miras alıyor
// Kopek.java
public class Kopek extends Hayvan { // extends ile miras alıyoruz
    String irk;

    public Kopek(String isim, String irk) {
        super(isim); // super() ile ana sınıfın kurucu metodunu çağırıyoruz
        this.irk = irk;
    }

    // Metot Ezme (Method Overriding): Ana sınıftaki metodu alt sınıfta yeniden tanımlama
    @Override // Bu annotation (işaretleme) metodun override edildiğini belirtir (iyi pratik)
    public void sesCikar() {
        System.out.println("Hav hav!"); // Ana sınıfın davranışını değiştiriyoruz
    }

    // Köpeğe özgü yeni metot
    public void getir() {
        System.out.println(this.isim + " bir şey getiriyor.");
    }
}

// Başka bir Alt Sınıf - Hayvan sınıfından miras alıyor
// Kedi.java
public class Kedi extends Hayvan {
    public Kedi(String isim) {
        super(isim); // Ana sınıfın kurucu metodunu çağır
    }

    @Override // sesCikar metodunu eziyoruz
    public void sesCikar() {
        System.out.println("Miyav!");
    }

    // Kediye özgü yeni metot
    public void tirman() {
        System.out.println(this.isim + " tırmanıyor.");
    }
}

// Main sınıfı (Test için ayrı bir yerde)
// TestHayvanlar.java
public class TestHayvanlar {
    public static void main(String[] args) {
        Hayvan hayvan = new Hayvan("Genel");
        Kopek kopek = new Kopek("Kont", "Golden");
        Kedi kedi = new Kedi("Tekir");

        hayvan.yemekYe(); // Miras alınmış metot
        kopek.yemekYe();  // Miras alınmış metot
        kedi.yemekYe();   // Miras alınmış metot

        hayvan.sesCikar(); // Ana sınıf metodu
        kopek.sesCikar();  // Ezilmiş (override edilmiş) metot
        kedi.sesCikar();   // Ezilmiş (override edilmiş) metot

        kopek.getir();    // Alt sınıfa özgü metot
        // kedi.getir(); // Hata verir, Kedi sınıfında yok!
    }
}
Açıklama: `extends Hayvan` ile `Kopek` ve `Kedi`, `Hayvan` sınıfından miras alır. `super(isim)` ile ana sınıfın kurucu metotları çağrılarak miras alınan özellikler (isim) başlatılır. `@Override` ile ana sınıftaki metotların alt sınıfta yeniden tanımlandığı belirtilir.

2. Çok Biçimlilik (Polymorphism) Java'da

Çok biçimlilik, farklı nesnelerin aynı metoda çağrı yapıldığında kendi tiplerine özgü farklı davranışlar sergilemesidir. Java'da bu, genellikle Miras Alma ile birlikte görülür. Bir ana sınıf referansı (değişkeni), o ana sınıftan türetilmiş herhangi bir alt sınıfın nesnesini tutabilir. Metot çağrıldığında ise Java, nesnenin gerçek (alt sınıf) tipine bakar ve o tipe ait metodu (eğer ezilmişse) çalıştırır.

Java:
// Önceki örnekteki Hayvan, Kopek, Kedi sınıflarının tanımlı olduğunu varsayalım

// Main sınıfı (Test için)
// TestPolymorphism.java
public class TestPolymorphism {
    public static void main(String[] args) {
        // Ana sınıf tipinde referanslar, alt sınıf nesnelerini tutuyor
        Hayvan hayvan1 = new Kopek("Lessi", "Collie"); // Hayvan referansı -> Kopek nesnesi
        Hayvan hayvan2 = new Kedi("Pamuk");      // Hayvan referansı -> Kedi nesnesi
        Hayvan hayvan3 = new Hayvan("Generic");   // Hayvan referansı -> Hayvan nesnesi

        // Hayvan nesneleri listesi oluşturma (farklı tipler bir arada)
        Hayvan[] hayvanDizisi = new Hayvan[3];
        hayvanDizisi[0] = hayvan1; // Kopek nesnesi
        hayvanDizisi[1] = hayvan2; // Kedi nesnesi
        hayvanDizisi[2] = hayvan3; // Hayvan nesnesi


        System.out.println("Hayvanlar sırayla ses çıkarıyor:");
        // Dizideki her nesne üzerinde döngü
        for (Hayvan h : hayvanDizisi) { // Referans tipi Hayvan olmasına rağmen...
            h.sesCikar(); // Java nesnenin gerçek tipine bakar ve doğru metodu çağırır
        }

        // Çıktı:
        // Hav hav!    (Kopek nesnesinin sesCikar metodu)
        // Miyav!     (Kedi nesnesinin sesCikar metodu)
        // Bir hayvan sesi (Hayvan nesnesinin sesCikar metodu)
    }
}
Açıklama: `Hayvan hayvan1 = new Kopek(...)` gibi atamalar çok biçimliliğin temelidir. Bir `Hayvan` referansı, herhangi bir `Hayvan` nesnesini veya `Hayvan`'dan miras alan bir alt sınıfın nesnesini gösterebilir. Döngü içinde `h.sesCikar()` çağrıldığında, Java derleme zamanında referans tipine (`Hayvan`) bakar, ancak çalışma zamanında nesnenin gerçek tipini (`Kopek`, `Kedi`, `Hayvan`) tespit eder ve o tipe ait `sesCikar` metodunu (eğer ezilmişse) çalıştırır. Bu, farklı nesne türlerini tek bir tip (ana sınıf tipi) üzerinden işleyerek esneklik sağlar.

3. Kapsülleme (Encapsulation) Java'da

Kapsülleme, bir nesnenin verilerini (özelliklerini) ve bu veriler üzerinde işlem yapan metotları tek bir birim (sınıf) içinde toplama ve veriye doğrudan erişimi engelleyerek kontrollü erişim sağlama prensibidir. Amaç, nesnenin iç durumunu dış dünyadan gizlemek ve veri tutarlılığını korumaktır.

Java'da Uygulama: Özellikleri `private` erişim belirteci ile tanımlanır (sadece sınıf içinden erişilebilir yapar). Bu özelliklere dışarıdan erişim için `public` Getter (`get...()`) ve Setter (`set...(...)`) metotları kullanılır.

Java:
// KapsullemeOrnegi.java
public class KapsullemeOrnegi {
    // Özellikleri private yaparak doğrudan erişimi engelliyoruz (Data Hiding)
    private String ad;
    private int yas;

    // Kurucu metot (Opsiyonel)
    public KapsullemeOrnegi(String ad, int yas) {
        this.ad = ad;
        // Setter kullanarak yaş atama, böylece setter'daki doğrulama çalışır
        setYas(yas);
    }

    // Getter metodu: 'ad' özelliğinin değerini dışarıya verir
    public String getAd() {
        return ad;
    }

    // Setter metodu: 'ad' özelliğine dışarıdan değer atama imkanı verir (Bu örnekte doğrudan atıyor)
    public void setAd(String ad) {
        this.ad = ad;
    }

    // Getter metodu: 'yas' özelliğinin değerini dışarıya verir
    public int getYas() {
        return yas;
    }

    // Setter metodu: 'yas' özelliğine dışarıdan değer atama imkanı verir
    // Değer atarken doğrulama yapabiliriz (veri tutarlılığını sağlama)
    public void setYas(int yas) {
        if (yas > 0 && yas < 120) { // Basit doğrulama
            this.yas = yas;
        } else {
            System.out.println("Hata: Geçersiz yaş değeri!");
        }
    }

    // Main metot (Test için)
    public static void main(String[] args) {
        KapsullemeOrnegi kisi = new KapsullemeOrnegi("Ali", 30);

        // Özelliklere doğrudan ERİŞİLEMEZ (private oldukları için compile time hatası verir)
        // System.out.println(kisi.ad); // Hata!
        // kisi.yas = 5;             // Hata!

        // Getter ve Setter metotları ile erişim ve değişiklik yapma
        System.out.println("Ad: " + kisi.getAd()); // Getter ile değeri al
        kisi.setYas(35); // Setter ile değeri değiştir
        System.out.println("Yaş: " + kisi.getYas()); // Getter ile yeni değeri al

        kisi.setYas(-5); // Geçersiz değer denemesi - Setter içindeki doğrulama çalışır
        System.out.println("Yaş (Geçersiz deneme sonrası): " + kisi.getYas()); // Yaş değişmemiş olmalı
    }
}
Açıklama: `private String ad;` tanımlaması, `ad` özelliğine sadece `KapsullemeOrnegi` sınıfının içinden erişilebileceğini belirtir. `public String getAd()` gibi Getter ve Setter metotları ise bu özel verilere dışarıdan kontrollü bir kapı açar. Setter metotlarının içine veri doğrulaması gibi ek mantıklar ekleyerek veri tutarlılığını sağlayabiliriz.

4. Soyutlama (Abstraction) Java'da

Soyutlama, karmaşık uygulama detaylarını gizleyerek sadece kullanıcının (veya başka geliştiricinin) ihtiyaç duyduğu temel özellikleri gösterme prensibidir. Odak noktası "Ne" yapıldığıdır, "Nasıl" yapıldığı detayları gizlenir.

Java'da Uygulama: Soyutlama genellikle Soyut Sınıflar (Abstract Classes) ve Arayüzler (Interfaces) kullanılarak sağlanır.

  • Soyut Sınıflar (`abstract class`):
    • `abstract` anahtar kelimesi ile tanımlanır.
    • Doğrudan nesnesi oluşturulamaz. (örneğin `new Sekil()` yapamazsınız).
    • Hem soyut metotlar (gövdesi olmayan, sadece imzası olan metotlar - alt sınıflar tarafından doldurulması zorunlu) hem de somut metotlar (gövdesi olan, normal metotlar) içerebilir.
    • Özellikler (değişkenler) içerebilir.
    • Soyut olmayan bir sınıf, soyut bir sınıftan miras alıyorsa (`extends`), ana sınıftaki tüm soyut metotları uygulamak (implement etmek) zorundadır.
    Java:
        // Soyut Sınıf Tanımı
        abstract class Sekil { // abstract anahtar kelimesi ile soyut sınıf
            String renk;
    
            public Sekil(String renk) {
                this.renk = renk;
            }
    
            // Soyut Metot - Gövdesi yok, alt sınıflar implement etmeli
            abstract double alanHesapla();
    
            // Somut Metot - Gövdesi var
            public void bilgiyiYazdir() {
                System.out.println("Bu bir " + renk + " şekildir.");
            }
        }
    
        // Soyut sınıftan miras alan somut sınıf
        class Daire extends Sekil {
            double yaricap;
    
            public Daire(String renk, double yaricap) {
                super(renk); // Ana sınıfın kurucusunu çağır
                this.yaricap = yaricap;
            }
    
            @Override // Soyut metodu implement etme zorunluluğu!
            double alanHesapla() { // abstract anahtar kelimesi kullanılmaz, govdesi yazilir
                return Math.PI * yaricap * yaricap;
            }
        }
    
        // Main (Test için)
        // TestSoyutSekil.java
        public class TestSoyutSekil {
            public static void main(String[] args) {
                // Sekil s = new Sekil("Kırmızı"); // Hata verir, soyut sınıftan nesne oluşturulamaz!
    
                Daire d = new Daire("Mavi", 5.0);
                d.bilgiyiYazdir(); // Miras alınan somut metot
                System.out.println("Alan: " + d.alanHesapla()); // Implement edilen soyut metot
            }
        }
  • Arayüzler (`interface`):
    • `interface` anahtar kelimesi ile tanımlanır.
    • Soyutlamanın en saf halidir. Java'da çoklu mirasın bir yolu olarak kullanılır (bir sınıf birden çok arayüzü uygulayabilir).
    • Java 8 öncesinde sadece soyut metotlar (public ve abstract varsayılan) ve sabitler (public static final varsayılan) içerebilirdi.
    • Java 8 sonrası `default` ve `static` metotlar da içerebilir.
    • Bir sınıf bir arayüzü uyguluyorsa (`implements`), arayüzdeki (default ve static olmayan) tüm metotları uygulamak zorundadır.
    • Bir sınıf birden çok arayüzü uygulayabilir (`class MyClass implements Interface1, Interface2 { ... }`).
    • Arayüzlerin doğrudan nesnesi oluşturulamaz.
    Java:
        // Arayüz Tanımı
        interface Cizebilir {
            // Metotlar varsayılan olarak public ve abstract'tır (Java 8 öncesi)
            void ciz(); // Soyut metot - govdesi yok
    
            // Java 8+ ile default metotlar
            default void bilgiVer() {
                System.out.println("Bu nesne çizilebilir.");
            }
        }
    
        // Arayüzü uygulayan sınıf
        class Kare implements Cizebilir { // implements ile arayuzu uyguluyoruz
            double kenar;
    
            public Kare(double kenar) {
                this.kenar = kenar;
            }
    
            @Override // Arayüzdeki metodu implement etme zorunluluğu!
            public void ciz() { // abstract anahtar kelimesi kullanılmaz, govdesi yazilir
                System.out.println("Kare çiziliyor (Kenar: " + kenar + ")");
            }
        }
    
         // Başka bir arayüzü uygulayan sınıf
         class Cember implements Cizebilir {
             double yaricap;
    
             public Cember(double yaricap) {
                 this.yaricap = yaricap;
             }
    
             @Override
             public void ciz() {
                 System.out.println("Çember çiziliyor (Yarıçap: " + yaricap + ")");
             }
         }
    
    
        // Main (Test için)
        // TestArayuz.java
        public class TestArayuz {
            public static void main(String[] args) {
                // Cizebilir c = new Cizebilir(); // Hata verir, arayüzden nesne oluşturulamaz!
    
                // Arayüz tipinde referans, uygulayan sınıfların nesnelerini tutabilir (Çok Biçimlilik!)
                Cizebilir sekil1 = new Kare(10.0);
                Cizebilir sekil2 = new Cember(5.0);
    
                sekil1.ciz(); // Kare'nin ciz() metodu çalışır
                sekil2.ciz(); // Cember'in ciz() metodu çalışır
    
                sekil1.bilgiVer(); // Arayüzdeki default metot
                sekil2.bilgiVer(); // Arayüzdeki default metot
            }
        }
    Açıklama: `implements Cizebilir` sözdizimi, `Kare` ve `Cember` sınıflarının `Cizebilir` arayüzündeki tüm soyut metotları (burada sadece `ciz()`) uygulamak zorunda olduğunu belirtir. Tıpkı soyut sınıflarda olduğu gibi, arayüz referansı da onu uygulayan herhangi bir sınıfın nesnesini gösterebilir ve bu nesne üzerinden arayüz metotları çağrıldığında nesnenin gerçek tipine ait implementasyon çalışır (Yine Çok Biçimlilik!).

Sıra Sizde!

Java'da OOP'nin dört ana prensibi (Miras Alma, Çok Biçimlilik, Kapsülleme, Soyutlama) program tasarımında çok önemlidir. Bu kavramları pekiştirmek için:

  • Miras Alma örneğini (Hayvan -> Kopek/Kedi) kendiniz Java'da kodlayıp çalıştırın. `super()` kullanımını farklı senaryolarda deneyin.
  • Çok Biçimlilik örneğini Java'da kodlayıp farklı alt sınıflardan nesneleri bir ana sınıf dizisinde/listesinde toplayarak metotları çağırmayı deneyin.
  • Kapsülleme örneğini (özellikleri `private` yapıp Getter/Setter ekleme) kendi bir sınıfınız üzerinde uygulayın. Setter metotlarına basit doğrulama kuralları eklemeyi deneyin.
  • Basit bir `abstract class` tanımlayın (örneğin `Calisan` soyut sınıfı, içinde `abstract double maasHesapla()` metodu olsun). Bu sınıftan miras alan somut sınıflar (örneğin `TamZamanliCalisan`, `YariZamanliCalisan`) tanımlayıp soyut metodu kendi mantıklarına göre implement edin.
  • Basit bir `interface` tanımlayın (örneğin `HareketEdebilir` arayüzü, içinde `void yuru()`, `void kos()` metotları olsun). Bu arayüzü uygulayan farklı sınıflar (`Insan`, `Robot`) tanımlayın ve metotları implement edin. Arayüz referansı üzerinden çok biçimliliği deneyin.
OOP'nin bu ileri kavramları, Java sözdizimi (`extends`, `implements`, `super`, `abstract`, `interface`, `@Override`, erişim belirteçleri) veya birbirleriyle ilişkileri hakkında aklınıza takılan soruları çekinmeden bu konu altında sorabilirsiniz.

Serinin Geleceği?[/B]

Java'da OOP'nin dört temel prensibini tamamladık. Bu, Java programlamada sağlam bir temel oluşturur.

Seriyi buradan sonra nasıl devam ettirelim?

  • Java'da temel kütüphane sınıfları ve veri yapıları (Diziler - Arrays, ArrayList, HashMap, String metotları, Scanner ile girdi alma, Dosya I/O)?
  • Java Hata Yönetimi (Exception Handling) derinlemesine ve kendi hata türlerini tanımlama?
  • Temel Veri Yapıları ve Algoritmalar (Bağlı Listeler, Ağaçlar, Grafikler vb.)?
  • Başka bir programlama diline giriş (C#, C++ gibi)?
  • Web geliştirme Frameworklerine giriş (Java Spring/Spring Boot, Python Flask/Django, JS React/Vue/Angular, PHP Laravel/Symfony)?
  • Mobil geliştirme temelleri (Android Studio ile)?
  • Belirli bir proje türüne odaklanma (Örn: Basit Java Konsol Uygulaması Yapımı, Basit Web API Yapımı)?
  • Veya başka önerileriniz mi var?
Geri bildirimleriniz ve önerileriniz serinin geleceğini şekillendirecektir.

Umarım bu konu OOP bilginizi Java özelinde daha da pekiştirmiştir. Görüşmek üzere!


Bu konu, "Hazır Kod Bankası" serisinin on sekizinci parçasıdır ve "Yazılım Bilgi ve Yeni Başlayanlar İçin" kategorisi altında paylaşılmıştır.
 

Şu an konuyu görüntüleyenler

Tema özelleştirme sistemi

Bu menüden forum temasının bazı alanlarını kendinize özel olarak düzenleye bilirsiniz

Zevkini yansıtan rengi seç

Geniş / Dar görünüm

Temanızı geniş yada dar olarak kullanmak için kullanabileceğiniz bir yapıyı kontrolünü sağlayabilirsiniz.

Izgara görünümlü forum listesi

Forum listesindeki düzeni ızgara yada sıradan listeleme tarzındaki yapının kontrolünü sağlayabilirsiniz.

Resimli ızgara modu

Izgara forum listesinde resimleri açıp/kapatabileceğiniz yapının kontrolünü sağlayabilirsiniz.

Kenar çubuğunu kapat

Kenar çubuğunu kapatarak forumdaki kalabalık görünümde kurtulabilirsiniz.

Sabit kenar çubuğu

Kenar çubuğunu sabitleyerek daha kullanışlı ve erişiminizi kolaylaştırabilirsiniz.

Köşe kıvrımlarını kapat

Blokların köşelerinde bulunan kıvrımları kapatıp/açarak zevkinize göre kullanabilirsiniz.

Geri