Ders İçeriği

Nesne Yönelimli Programlama (Object-Oriented Programming - OOP), modern yazılım geliştirmenin temelini oluşturan bir programlama paradigmasıdır. Java, tamamen nesne yönelimli bir dil olup, OOP prensiplerini güçlü bir şekilde destekler. Bu bölümde, OOP'nin temel kavramlarını, yani sınıf, nesne, kalıtım, polimorfizm, soyutlama ve kapsüllemeyi detaylı bir şekilde inceleyeceğiz.

1. Sınıf (Class)

Sınıf, nesnelerin özelliklerini (veri) ve davranışlarını (metotlar) tanımlayan bir şablondur veya taslaktır. Bir sınıf, belirli bir türdeki nesnelerin nasıl oluşturulacağını ve nasıl davranacağını belirler. Sınıflar, gerçek dünyadaki varlıkların veya kavramların soyut bir temsilidir.

Örnek: Bir Araba sınıfı düşünelim. Bu sınıfın özellikleri (marka, model, renk, hız) ve davranışları (hızlan, yavaşla, dur) olabilir.

public class Araba {
    // Özellikler (Veri - Alanlar/Değişkenler)
    String marka;
    String model;
    String renk;
    int hiz;

    // Davranışlar (Metotlar)
    public void hizlan(int artis) {
        hiz += artis;
        System.out.println(marka + " " + model + " hızı: " + hiz);
    }

    public void yavasla(int azalis) {
        hiz -= azalis;
        System.out.println(marka + " " + model + " hızı: " + hiz);
    }

    public void dur() {
        hiz = 0;
        System.out.println(marka + " " + model + " durdu.");
    }
}

2. Nesne (Object)

Nesne, bir sınıfın somut bir örneğidir. Bir sınıf tanımlandıktan sonra, o sınıftan istediğimiz kadar nesne oluşturabiliriz. Her nesne, sınıfın tanımladığı özelliklere ve davranışlara sahip olur, ancak kendi benzersiz veri değerlerine sahip olabilir.

Örnek: Yukarıdaki Araba sınıfından iki farklı nesne oluşturalım.

public class Main {
    public static void main(String[] args) {
        // Araba sınıfından iki nesne oluşturma
        Araba araba1 = new Araba();
        Araba araba2 = new Araba();

        // araba1 nesnesinin özelliklerini ayarlama
        araba1.marka = "Toyota";
        araba1.model = "Corolla";
        araba1.renk = "Beyaz";
        araba1.hiz = 0;

        // araba2 nesnesinin özelliklerini ayarlama
        araba2.marka = "Honda";
        araba2.model = "Civic";
        araba2.renk = "Mavi";
        araba2.hiz = 0;

        // Nesnelerin metotlarını çağırma
        araba1.hizlan(50); // Toyota Corolla hızı: 50
        araba2.hizlan(70); // Honda Civic hızı: 70
        araba1.dur();     // Toyota Corolla durdu.
    }
}

3. Kalıtım (Inheritance)

Kalıtım, bir sınıfın (alt sınıf veya türetilmiş sınıf) başka bir sınıfın (üst sınıf veya temel sınıf) özelliklerini ve davranışlarını miras almasını sağlayan bir OOP prensibidir. Bu, kodun yeniden kullanılabilirliğini artırır ve hiyerarşik bir yapı oluşturur. Java'da extends anahtar kelimesi ile kalıtım sağlanır.

Örnek: Araba sınıfından türeyen bir SporAraba sınıfı oluşturalım. Spor arabalar, normal arabaların tüm özelliklerine ek olarak kendi özel özelliklerine (örneğin, turbo) sahip olabilir.

public class SporAraba extends Araba {
    boolean turbo;

    public void turboAc() {
        turbo = true;
        System.out.println(marka + " " + model + " turbo açıldı!");
    }
}

// Main metodunda kullanımı
SporAraba sporAraba = new SporAraba();
sporAraba.marka = "Ferrari";
sporAraba.model = "488";
sporAraba.hizlan(100); // Araba sınıfından miras alınan metot
sporAraba.turboAc();   // SporAraba sınıfına özgü metot

4. Polimorfizm (Polymorphism)

Polimorfizm, "çok biçimlilik" anlamına gelir. OOP'de polimorfizm, farklı nesnelerin aynı mesaja farklı şekillerde yanıt verebilmesi yeteneğidir. Java'da polimorfizm iki şekilde sağlanır:

  • Metot Aşırı Yüklemesi (Method Overloading): Aynı sınıf içinde, aynı isme sahip ancak farklı parametre listelerine (sayı, tip veya sıra) sahip metotlar tanımlamaktır.
  • Metot Geçersiz Kılma (Method Overriding): Alt sınıfın, üst sınıftan miras aldığı bir metodu kendi ihtiyacına göre yeniden tanımlamasıdır.

Örnek (Metot Geçersiz Kılma): Araba sınıfındaki hizlan metodunu SporAraba sınıfında geçersiz kılalım.

public class SporAraba extends Araba {
    boolean turbo;

    @Override
    public void hizlan(int artis) {
        super.hizlan(artis * 2); // Spor arabalar daha hızlı hızlanır
        System.out.println("Spor araba özel hızlanma: " + hiz);
    }

    public void turboAc() {
        turbo = true;
        System.out.println(marka + " " + model + " turbo açıldı!");
    }
}

// Main metodunda kullanımı
Araba genelAraba = new Araba();
genelAraba.marka = "Fiat";
genelAraba.model = "Egea";
genelAraba.hizlan(30); // Fiat Egea hızı: 30

SporAraba sporAraba = new SporAraba();
sporAraba.marka = "Porsche";
sporAraba.model = "911";
sporAraba.hizlan(30); // Porsche 911 hızı: 60 (geçersiz kılınan metot çalışır)

5. Soyutlama (Abstraction)

Soyutlama, karmaşık sistemlerin detaylarını gizleyerek sadece gerekli bilgileri gösterme prensibidir. Kullanıcıya sadece önemli olanı sunar ve iç işleyişi gizler. Java'da soyutlama, soyut sınıflar (abstract class) ve arayüzler (interface) aracılığıyla sağlanır.

  • Soyut Sınıf: En az bir soyut metot içeren sınıftır. Soyut metotların gövdesi yoktur ve alt sınıflar tarafından uygulanması gerekir. Soyut sınıflardan doğrudan nesne oluşturulamaz.
  • Arayüz (Interface): Tamamen soyut metotlar (Java 8'den itibaren varsayılan ve statik metotlar da içerebilir) ve sabitler içeren bir yapıdır. Bir sınıf birden fazla arayüzü uygulayabilir (implements).

Örnek (Soyut Sınıf):

public abstract class Sekil {
    String renk;

    public Sekil(String renk) {
        this.renk = renk;
    }

    public abstract double alanHesapla(); // Soyut metot

    public void renkGoster() {
        System.out.println("Şeklin rengi: " + renk);
    }
}

public class Daire extends Sekil {
    double yaricap;

    public Daire(String renk, double yaricap) {
        super(renk);
        this.yaricap = yaricap;
    }

    @Override
    public double alanHesapla() {
        return Math.PI * yaricap * yaricap;
    }
}

// Main metodunda kullanımı
// Sekil sekil = new Sekil("Kırmızı"); // Hata: Soyut sınıftan nesne oluşturulamaz
Daire daire = new Daire("Mavi", 5);
daire.renkGoster(); // Şeklin rengi: Mavi
System.out.println("Dairenin alanı: " + daire.alanHesapla()); // Dairenin alanı: 78.53...

6. Kapsülleme (Encapsulation)

Kapsülleme, veriyi (alanlar) ve bu veri üzerinde işlem yapan metotları tek bir birim (sınıf) içinde bir araya getirme ve dışarıdan doğrudan erişimi kısıtlama prensibidir. Bu, verinin yanlışlıkla değiştirilmesini önler ve kodun daha güvenli ve bakımı kolay olmasını sağlar. Kapsülleme genellikle alanları private yaparak ve bu alanlara erişim için public getter ve setter metotları sağlayarak gerçekleştirilir.

Örnek: Araba sınıfındaki hiz özelliğini kapsülleyelim.

public class ArabaKapsul {
    private String marka;
    private String model;
    private int hiz; // private yapıldı

    // Constructor
    public ArabaKapsul(String marka, String model) {
        this.marka = marka;
        this.model = model;
        this.hiz = 0;
    }

    // Getter metodu
    public int getHiz() {
        return hiz;
    }

    // Setter metodu (hızın negatif olmasını engellemek için kontrol eklendi)
    public void setHiz(int yeniHiz) {
        if (yeniHiz >= 0) {
            this.hiz = yeniHiz;
        } else {
            System.out.println("Hız negatif olamaz!");
        }
    }

    public void hizlan(int artis) {
        setHiz(this.hiz + artis); // Setter metodu kullanıldı
        System.out.println(marka + " " + model + " hızı: " + getHiz());
    }

    public void yavasla(int azalis) {
        setHiz(this.hiz - azalis); // Setter metodu kullanıldı
        System.out.println(marka + " " + model + " hızı: " + getHiz());
    }
}

// Main metodunda kullanımı
ArabaKapsul araba = new ArabaKapsul("BMW", "X5");
araba.hizlan(60); // BMW X5 hızı: 60
araba.setHiz(-10); // Hız negatif olamaz!
System.out.println("Güncel hız: " + araba.getHiz()); // Güncel hız: 60

Nesne Yönelimli Programlama kavramları, büyük ve karmaşık yazılım projelerini yönetilebilir, esnek ve sürdürülebilir hale getirmek için hayati öneme sahiptir. Bu prensipleri anlamak ve uygulamak, daha iyi Java geliştiricileri olmanızı sağlayacaktır. Bir sonraki derste Java Koleksiyonlar Çerçevesi'ni inceleyeceğiz.