Sınıf, nesne, self, __init__ ve metotlar
Artık kendi nesne türlerimizi tanımlayabiliriz. Bir sınıf (class), belirli türde nesnelerin hangi duruma ve davranışlara sahip olacağını tanımlar. Sınıftan oluşturulan her örnek (instance) kendi durumunu taşır.
Bu hafta neleri yapabilmelisiniz?
- sınıf ile nesne/örnek ayrımını açıklayabilmeli,
classile sınıf tanımlayabilmeli,__init__içinde örnek nitelikleri oluşturabilmeli,selfparametresinin hangi nesneyi temsil ettiğini açıklayabilmeli,- örnek metodu yazıp çağırabilmeli,
- durum değişimini metot üzerinden gerçekleştirebilmeli,
- aynı sınıftan iki nesnenin bağımsız durum taşıdığını gösterebilmeli,
- sınıf niteliği ile örnek niteliğinin farkını açıklayabilmelisiniz.
İlk sınıfımız
BankAccount sınıftır; account ise bu sınıftan oluşturulmuş bir nesneye referanstır.
__init__, yeni örnek oluşturulurken başlangıç durumunu ayarlamak için kullanılan özel metottur.
__init__ “nesneyi yoktan yaratan fonksiyon” diye düşünülmemeli
Başlangıç düzeyinde “constructor” sözcüğü yaygın kullanılır; ancak Python veri modelinde nesnenin oluşturulması ile başlatılması ayrıdır. Bu derste ayrıntılı __new__ konusuna girmiyoruz. Pratik olarak __init__’i nesnenin başlangıç durumunu kurduğumuz metot olarak kullanacağız.

__init__ içinde parametrelerin self üzerinden oluşturulan nesnenin alanlarına aktarılması.self nedir?
Aynı sınıftan iki hesap oluşturalım:
self, metot çağrısının yapıldığı o anki nesneye erişmemizi sağlar. first üzerinden çağrılan metotta self → first nesnesidir; second üzerinden çağrıda self → second nesnesidir.

self değerinin çağrıyı alan nesne olması ve metodun bu nesnenin durumunu değiştirmesi.Davranışı sınıfa eklemek
account.deposit(50) çağrısını zihinsel olarak şu biçimde düşünebilirsiniz:
BankAccount.deposit(account, 50)Normal kullanımda ilk biçimi tercih ederiz; ikinci biçim self’in nereden geldiğini anlamak için yararlıdır.
Metot yalnızca “fonksiyon sınıf içinde” değildir
Teknik olarak örnek metodu sınıf içinde tanımlanan ve nesne üzerinden bağlanan bir fonksiyondur. Tasarım açısından ise daha önemli bir fikir vardır:
Metot, nesnenin sorumluluğuna ait davranışı ifade eder.
deposit() davranışının BankAccount içinde olması, bakiye değişikliğinin hesap nesnesinin sorumluluğunda olduğunu söyler.
Aynı sınıftan bağımsız nesneler
Her nesne kendi value durumunu taşır.

Sınıf niteliği ile örnek niteliği aynı şey değildir
self.value gibi __init__ içinde oluşturulan nitelikler çoğunlukla örnek niteliğidir (instance attribute). Her nesne kendi değerini taşır.
Buna karşılık sınıf gövdesinde tanımlanan nitelik sınıf tarafından paylaşılır:
name her öğrenci nesnesine özgüdür. school ise sınıfta tanımlanmıştır ve örnekler aynı sınıf niteliğini görebilir.

Bu fark özellikle değiştirilebilir nesnelerde önemlidir. Aşağıdaki kodu çalıştırmadan önce sonucu tahmin edin:
members sınıf niteliği olduğu için iki nesne de aynı listeyi görür. Her takımın bağımsız üye listesine sahip olmasını istiyorsak listeyi __init__ içinde oluşturmalıyız:
class Team:
def __init__(self, name):
self.name = name
self.members = []Sınıf niteliği gerçekten bütün örneklerce paylaşılacak veri için anlamlı olabilir. Ancak her nesnenin kendi listesi, sözlüğü veya kümesi olması gerekiyorsa bu mutable nesneyi sınıf gövdesinde değil, __init__ içinde örnek niteliği olarak oluşturun.
Sorumluluğu doğru yere koymak
Şu iki tasarımı karşılaştırın:
# A: dışarıdan doğrudan güncelleme
account.balance -= 100# B: davranış üzerinden güncelleme
account.withdraw(100)İkinci yaklaşım, “para çekmenin kuralları hesabın sorumluluğundadır” dememizi sağlar. Gelecek hafta withdraw içinde geçerli durum kurallarını koruyacağız.
Alıştırma — Sınıfı tamamla
self.price *= (1 - rate)Alıştırma — self hatasını bul
Aşağıdaki sınıfta hata var:
Lamp().turn_on() çağrısında ne olur? Metot tanımındaki eksikliği düzeltin ve tekrar deneyin.
Alıştırma — İki nesnenin durumunu izle
Çalıştırmadan önce çıktıyı tahmin edin. Sonra her çağrıdan sonra iki nesnenin durumunu tablo hâlinde yazın.
Alıştırma — Paylaşılan liste hatasını düzelt
Aşağıdaki tasarımda iki sepetin ürünleri yanlışlıkla ortak listeyi kullanıyor:
Her sepetin kendi items listesine sahip olması için sınıfı düzeltin. Değiştirilebilir listenin neden __init__ içinde oluşturulması gerektiğini bir cümleyle açıklayın.
Küçük üretim görevi — Book sınıfı
Bir Book sınıfı oluşturun:
titleauthoris_borrowed
niteliklerine sahip olsun. Başlangıçta is_borrowed = False olsun.
İki metot ekleyin:
borrow()→ kitabı ödünç alınmış yapar,return_book()→ kitabı geri verilmiş yapar.
İki ayrı kitap nesnesi oluşturun ve birini ödünç almanın diğerini değiştirmediğini gösterin.
Şimdilik aynı kitabı iki kez ödünç alma gibi geçersiz durumları engellemiyoruz. Gelecek hafta tam olarak bunu yapacağız.
Kendinizi kontrol edin
- Sınıf ile nesne arasındaki fark nedir?
selfhangi nesneyi temsil eder?__init__ne zaman çalışır ve temel amacı nedir?- Aynı sınıftan iki nesnenin nitelikleri neden bağımsız olabilir?
- Sınıf niteliği ile örnek niteliği arasındaki fark nedir?
- Mutable bir listeyi sınıf gövdesinde tanımlamak hangi durumda sorun yaratabilir?
- Bir davranışı metoda dönüştürmek yalnızca kod organizasyonu mudur, yoksa sorumluluk kararı da mıdır?
Bu haftadan akılda kalması gerekenler
- Sınıf bir tür/şablon tanımı; nesne o sınıfın çalışma anındaki örneğidir.
self, çağrının hedefindeki nesneye erişim sağlar.__init__başlangıç durumunu kurar.- Örnek nitelikleri nesneye özgü durum taşır; sınıf nitelikleri sınıf düzeyinde paylaşılabilir.
- Her nesnenin kendi mutable koleksiyonu gerekiyorsa koleksiyonu
__init__içinde oluşturun. - Örnek metotları nesnenin davranışlarını ifade eder.
- İyi OOP tasarımında soru “hangi sınıfa hangi kodu koyarım?” değil, “bu davranış kimin sorumluluğu?”dur.