Sınıf ve Nesne Kavramı
Programlama öğrenirken bir noktada "tamam, fonksiyonlarla her şeyi yapabiliyorum ama bu kod neden bu kadar dağınık?" diye düşünmeye başlarsın. Değişkenler bir yerde, fonksiyonlar başka yerde, hangi fonksiyon hangi veriyle çalışıyor belli değil. İşte Object-Oriented Programming (OOP) tam da bu karmaşayı çözmek için var.
Bu derste OOP'nin temel yapı taşlarını — sınıf ve nesne kavramlarını — sıfırdan öğreneceğiz. Merak etme, düşündüğün kadar karmaşık değil.
OOP Nedir?
OOP, yani Nesne Yönelimli Programlama, gerçek dünyayı kod ile modelleme yaklaşımıdır. Etrafına bir bak: masanın üzerindeki telefon, elindeki kalem, ekrandaki tarayıcı penceresi… Hepsi birer nesne. Her nesnenin özellikleri (rengi, boyutu, markası) ve davranışları (açılır, kapanır, yazı yazar) var.
OOP diyor ki: "Madem gerçek dünya nesnelerden oluşuyor, yazılımı da nesnelerle modelleyelim." Bu kadar basit aslında.
Prosedürel vs OOP
Şimdiye kadar büyük ihtimalle prosedürel tarzda kod yazdın. Yani fonksiyonlar tanımladın, değişkenler oluşturdun ve bunları bir sırayla çağırdın. Bu yaklaşım küçük programlar için gayet iyi çalışır. Ama program büyüdükçe şöyle sorunlar çıkar:
Hangi fonksiyon hangi veriyle çalışıyor? Belli değil.
Aynı tür veriler için aynı fonksiyonları tekrar tekrar yazıyorsun.
Bir yerde bir şeyi değiştirdin, başka yerde her şey bozuldu.
# Prosedürel yaklaşım — dağınık
student_name = "Ali"
student_grade = 85
student_passed = True
def print_student(name, grade, passed):
status = "Geçti" if passed else "Kaldı"
print(f"{name}: {grade} — {status}")
def is_honor(grade):
return grade >= 90
print_student(student_name, student_grade, student_passed)Bu kodda öğrenci verileri havada uçuşuyor. 50 öğrenci olsa ne yapacaksın? Her biri için ayrı değişken mi? Liste mi? Sözlük mü? Karmaşıklaşmaya başlıyor.
# OOP yaklaşım — düzenli
class Student:
def __init__(self, name, grade):
self.name = name
self.grade = grade
self.passed = grade >= 50
def print_info(self):
status = "Geçti" if self.passed else "Kaldı"
print(f"{self.name}: {self.grade} — {status}")
def is_honor(self):
return self.grade >= 90
ali = Student("Ali", 85)
ali.print_info()Gördün mü farkı? Veri ve davranış bir arada. Öğrencinin adı, notu ve fonksiyonları hep aynı yerde. Bu düzeni sağlayan şey sınıf kavramı.
Sınıf ve Nesne — Kurabiye Kalıbı Analojisi 🍪
OOP'nin en temel iki kavramı sınıf (class) ve nesne (object). Aralarındaki farkı anlamak için şu analojiyi düşün:
Sınıf = Kurabiye kalıbı. Kalıbın kendisi kurabiye değildir. Ama ondan kurabiye üretirsin. Kalıp yıldız şeklindeyse, ürettiğin her kurabiye yıldız şeklinde olur.
Nesne = Kalıptan çıkan kurabiye. Her kurabiye aynı şekle sahiptir (çünkü aynı kalıptan çıktı) ama farklı süslemeleri olabilir — biri çikolatalı, biri kremalı.
Programlama terimleriyle:
Sınıf: Bir şeyin nasıl olacağını tanımlayan şablon/blueprint.
Nesne: O şablondan üretilen somut bir örnek (instance).
# Sınıf = kalıp
class Cookie:
shape = "star" # Her kurabiye yıldız şeklinde
# Nesne = kalıptan üretilen kurabiyeler
cookie1 = Cookie()
cookie2 = Cookie()
print(cookie1.shape) # star
print(cookie2.shape) # star
# Ama her nesne bağımsız
cookie1.topping = "chocolate"
cookie2.topping = "cream"
print(cookie1.topping) # chocolate
print(cookie2.topping) # creamBir sınıftan istediğin kadar nesne üretebilirsin. Her nesne bağımsız bir varlıktır — birini değiştirmek diğerini etkilemez.
class Keyword ile Sınıf Tanımlama
Python'da sınıf tanımlamak için class anahtar kelimesini kullanırsın. Söz dizimi şöyle:
class ClassName:
# sınıfın gövdesi
passBirkaç kural:
Sınıf adları PascalCase yazılır:
MyClass,StudentRecord,BankAccount. Bu bir zorunluluk değil ama Python topluluğunun güçlü bir convention'ıdır. PEP 8'e uygun kod yazmak istiyorsan buna uy.passboş bir sınıf için yer tutucu. Gövdesi olmayan sınıftapassyazmazsanızSyntaxErroralırsınız.
class Dog:
species = "Canis familiaris"
def bark(self):
return "Hav hav!"Bu sınıf bir köpeği modelliyor. species bir sınıf özelliği (class attribute), bark() ise bir metod (method). Metod, sınıfın içinde tanımlanan bir fonksiyondur. self parametresini şimdilik "nesnenin kendisi" olarak düşün, bir sonraki derste detaylıca konuşacağız.
En Basit Sınıf
class Empty:
pass
obj = Empty()
print(type(obj)) # <class '__main__.Empty'>Evet, pass ile bile geçerli bir sınıf oluşturabilirsin. Bu sınıftan nesne üretebilir, hatta sonradan özellik ekleyebilirsin. Python bu konuda çok esnek.
Nesne Oluşturma (Instantiation)
Sınıftan nesne üretmeye instantiation denir. Bir sınıfı fonksiyon gibi çağırdığında yeni bir nesne yaratılır:
class Car:
def __init__(self, brand, year):
self.brand = brand
self.year = year
def describe(self):
return f"{self.year} model {self.brand}"
# Nesne oluşturma
car1 = Car("Toyota", 2020)
car2 = Car("Honda", 2022)
print(car1.describe()) # 2020 model Toyota
print(car2.describe()) # 2022 model HondaHer Car(...) çağrısı yeni bir nesne yaratır. car1 ve car2 aynı sınıftan geliyorlar ama farklı verilere sahipler. Bu, OOP'nin güzelliği — bir kere tanımla, istediğin kadar üret.
Nesneye Sonradan Özellik Ekleme
Python dinamik bir dil olduğu için, nesneye sınıf tanımında olmayan özellikler de ekleyebilirsin:
class Person:
pass
p = Person()
p.name = "Ayşe"
p.age = 25
print(p.name) # Ayşe
print(p.age) # 25Bu çalışır ama önerilmez. Neden? Çünkü hangi nesnenin hangi özelliklere sahip olduğunu takip etmek zorlaşır. Sınıfın __init__ metodunda tüm özellikleri tanımlamak çok daha iyi bir pratiktir.
💡 İpucu: Python'da sınıf tanımlarken tüm instance attribute'ları
__init__içinde tanımla. Bu, kodunu okuyan herkesin "bu nesnenin hangi özellikleri var?" sorusuna tek bir yere bakarak cevap bulmasını sağlar.
Sınıf vs Instance
Bu ayrımı iyi anlamak çok önemli çünkü ileride "class attribute" ve "instance attribute" farkı karşına sıkça çıkacak.
Sınıf (Class): Şablonun kendisi. Bellekte tek bir yerde durur. Tüm nesneler bu şablonu paylaşır.
Instance (Nesne): Şablondan üretilen somut örnek. Her birinin bellekte ayrı bir adresi vardır.
class Circle:
pi = 3.14159 # Class attribute — tüm daireler için aynı
def __init__(self, radius):
self.radius = radius # Instance attribute — her daire için farklı
def area(self):
return Circle.pi * self.radius ** 2
c1 = Circle(5)
c2 = Circle(10)
print(c1.area()) # 78.53975
print(c2.area()) # 314.159
# Aynı sınıftan mı?
print(type(c1)) # <class '__main__.Circle'>
print(type(c1) == type(c2)) # True
# Ama farklı nesneler
print(c1 is c2) # False
print(id(c1)) # farklı bellek adresi
print(id(c2)) # farklı bellek adresipi bir class attribute — tüm Circle nesneleri aynı pi değerini paylaşıyor. radius ise instance attribute — her dairenin kendi yarıçapı var.
type() ve isinstance()
Bir nesnenin hangi sınıftan geldiğini kontrol etmek için:
class Animal:
pass
class Dog(Animal):
pass
buddy = Dog()
print(type(buddy)) # <class '__main__.Dog'>
print(type(buddy) == Dog) # True
print(type(buddy) == Animal) # False — type() tam sınıfı kontrol eder
print(isinstance(buddy, Dog)) # True
print(isinstance(buddy, Animal)) # True — isinstance() kalıtımı da kontrol edertype() tam eşleşme arar. isinstance() ise kalıtım zincirini de kontrol eder (kalıtımı ileride göreceğiz). Genel olarak isinstance() kullanmak daha güvenlidir.
dir() ile Nesnenin Özelliklerini Keşfetme
Python'da bir nesnenin neler yapabildiğini öğrenmek istiyorsan dir() fonksiyonu arkadaşın:
class Robot:
def __init__(self, name):
self.name = name
def greet(self):
return f"Merhaba, ben {self.name}!"
r = Robot("R2D2")
print(dir(r))Bu çıktı oldukça uzun olacak. __init__, __str__, __eq__ gibi çift alt çizgili bir sürü şey göreceksin. Bunlar magic methods (sihirli metodlar) — Python'un arka planda her nesneye otomatik eklediği özel metodlar. İleride bunları detaylıca göreceğiz.
Şimdilik önemli olan: dir() ile bir nesnenin tüm özellik ve metodlarını listeleyebilirsin. Bu, özellikle yeni bir kütüphaneyle çalışırken çok işe yarar.
# Sadece kendi tanımladıklarımızı görelim
attrs = [a for a in dir(r) if not a.startswith('_')]
print(attrs) # ['greet', 'name']Alt çizgiyle başlamayanları filtreleyerek sadece "bizim" özellikleri görebilirsin.
help() Fonksiyonu
dir() özellikleri listeler ama ne işe yaradığını söylemez. help() fonksiyonu ise docstring'leri gösterir:
class Calculator:
"""Basit bir hesap makinesi sınıfı."""
def add(self, a, b):
"""İki sayıyı toplar."""
return a + b
def multiply(self, a, b):
"""İki sayıyı çarpar."""
return a * b
calc = Calculator()
help(calc)Bu, sınıfın ve metodlarının dökümanını güzel bir formatta gösterir. Kendi sınıflarını yazarken docstring eklemeyi alışkanlık edin — gelecekteki sen teşekkür edecek.
Python'da Her Şey Nesne
Python'ın en güzel özelliklerinden biri: her şey bir nesnedir. Sayılar, string'ler, listeler, fonksiyonlar, hatta sınıfların kendisi bile birer nesne.
# Sayılar nesne
x = 42
print(type(x)) # <class 'int'>
print(x.bit_length()) # 6 — 42'nin binary gösterimi 6 bit
# String'ler nesne
s = "hello"
print(type(s)) # <class 'str'>
print(s.upper()) # HELLO
# Listeler nesne
lst = [1, 2, 3]
print(type(lst)) # <class 'list'>
lst.append(4) # metod çağırıyoruz çünkü nesne!
# Fonksiyonlar bile nesne
def greet():
return "Merhaba!"
print(type(greet)) # <class 'function'>
print(greet.__name__) # greetBu neden önemli? Çünkü Python'da OOP öğrenirken aslında "yeni bir paradigma" öğrenmiyorsun — zaten OOP kullanıyordun! "hello".upper() yazdığında bir nesnenin metodunu çağırıyordun. Sadece farkında değildin.
Sınıflar da Nesne
Hatta sınıfların kendisi de birer nesne. Her sınıf type sınıfının bir instance'ı:
class Foo:
pass
print(type(Foo)) # <class 'type'>
print(type(int)) # <class 'type'>
print(type(str)) # <class 'type'>
# type'ın tipi ne?
print(type(type)) # <class 'type'> — kendisinin instance'ı!Bu biraz kafa karıştırıcı olabilir ve şu an tam anlamak zorunda değilsin. Ama şunu bil: Python'da her şeyin bir tipi var ve her tip bir sınıf. Bu tutarlılık, dilin gücünün kaynağıdır.
Nesne Kimliği: id() ve is
Her nesnenin Python'da benzersiz bir kimliği (identity) vardır. Bu kimliği id() fonksiyonuyla görebilirsin:
a = [1, 2, 3]
b = [1, 2, 3]
c = a
print(id(a)) # 140234567890 (örnek)
print(id(b)) # 140234567950 (farklı!)
print(id(c)) # 140234567890 (a ile aynı!)a ve b aynı değere sahip ama farklı nesneler. c ise a'nın kendisi — aynı nesneye farklı bir isim verdik.
== vs is
a = [1, 2, 3]
b = [1, 2, 3]
c = a
# == değer karşılaştırması
print(a == b) # True — değerleri aynı
# is kimlik karşılaştırması
print(a is b) # False — farklı nesneler
print(a is c) # True — aynı nesne== iki nesnenin değerinin aynı olup olmadığını kontrol eder. is ise iki değişkenin aynı nesneye mi referans verdiğini kontrol eder.
⚠️ Dikkat:
isoperatörünü genellikle sadeceNonekontrolü için kullan:if x is None. Değer karşılaştırması için her zaman==kullan. Python bazı küçük tamsayıları ve kısa stringleri cache'lediği içinisbeklenmedik sonuçlar verebilir.
# Python küçük tamsayıları cache'ler (-5 ile 256 arası)
x = 256
y = 256
print(x is y) # True — cache'lenmiş
x = 257
y = 257
print(x is y) # False — farklı nesneler (implementasyona bağlı)Sınıfın Anatomisi
Bir sınıfı parçalarına ayıralım:
class BankAccount:
"""Basit bir banka hesabı sınıfı."""
# Class attribute
bank_name = "Python Bank"
account_count = 0
def __init__(self, owner, balance=0):
"""Yeni hesap oluşturur."""
self.owner = owner # Instance attribute
self.balance = balance # Instance attribute
BankAccount.account_count += 1
def deposit(self, amount):
"""Hesaba para yatırır."""
if amount > 0:
self.balance += amount
return True
return False
def withdraw(self, amount):
"""Hesaptan para çeker."""
if 0 < amount <= self.balance:
self.balance -= amount
return True
return False
def get_info(self):
"""Hesap bilgilerini döner."""
return f"{self.owner} — {self.bank_name} — Bakiye: {self.balance} TL"Bu sınıfta neler var:
Docstring: Sınıfın ne yaptığını açıklayan metin.
Class attributes:
bank_nameveaccount_count— tüm nesneler tarafından paylaşılır.`__init__` metodu: Nesne oluşturulduğunda çağrılır (constructor).
Instance attributes:
self.ownerveself.balance— her nesneye özel.Instance methods:
deposit(),withdraw(),get_info()— nesne üzerinde çalışan fonksiyonlar.
# Kullanım
acc1 = BankAccount("Ali", 1000)
acc2 = BankAccount("Ayşe", 2000)
acc1.deposit(500)
acc2.withdraw(300)
print(acc1.get_info()) # Ali — Python Bank — Bakiye: 1500 TL
print(acc2.get_info()) # Ayşe — Python Bank — Bakiye: 1700 TL
print(BankAccount.account_count) # 2OOP'nin 4 Temel Prensibi
OOP dört temel prensip üzerine kuruludur. Bu derste sadece genel bir bakış yapacağız — her birini ilerleyen derslerde derinlemesine işleyeceğiz.
1. Encapsulation (Kapsülleme)
Veri ve o veriyle çalışan metodları bir arada tutmak. Ayrıca veriye doğrudan erişimi kısıtlayıp, kontrollü bir arayüz sunmak.
class TemperatureSensor:
def __init__(self):
self._temperature = 0 # "private" — dışarıdan dokunma
def get_temperature(self):
return self._temperature
def set_temperature(self, value):
if -50 <= value <= 150:
self._temperature = value
else:
raise ValueError("Geçersiz sıcaklık değeri!")Dışarıdan _temperature'a doğrudan erişmek yerine, kontrollü metodlar kullanıyoruz. Bu sayede geçersiz değerler engellenebilir.
2. Inheritance (Kalıtım)
Bir sınıfın başka bir sınıftan özellik ve davranış devralması. Kod tekrarını azaltır.
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return "..."
class Dog(Animal):
def speak(self):
return "Hav hav!"
class Cat(Animal):
def speak(self):
return "Miyav!"
buddy = Dog("Buddy")
print(buddy.name) # Buddy — Animal'dan miras
print(buddy.speak()) # Hav hav! — Dog'a özelDog ve Cat sınıfları Animal'dan miras alıyor. name özelliğini yeniden tanımlamak zorunda değiller.
3. Polymorphism (Çok Biçimlilik)
Farklı sınıfların aynı arayüzü (metod adını) farklı şekillerde uygulaması.
animals = [Dog("Rex"), Cat("Whiskers"), Dog("Max")]
for animal in animals:
print(f"{animal.name}: {animal.speak()}")
# Rex: Hav hav!
# Whiskers: Miyav!
# Max: Hav hav!speak() metodunu çağırıyoruz ama her nesne kendi versiyonunu çalıştırıyor. İşte polimorfizm bu — aynı isim, farklı davranış.
4. Abstraction (Soyutlama)
Karmaşık detayları gizleyip, kullanıcıya sadece gerekli arayüzü sunmak.
class EmailSender:
def send(self, to, subject, body):
"""E-posta gönderir."""
self._connect_to_server()
self._authenticate()
self._compose_message(to, subject, body)
self._send_message()
self._disconnect()
def _connect_to_server(self):
# Karmaşık bağlantı kodu...
pass
def _authenticate(self):
# Karmaşık kimlik doğrulama...
pass
# ... diğer private metodlarKullanıcı sadece send() metodunu bilmek zorunda. Arka plandaki karmaşık adımlar gizlenmiş durumda.
Gerçek Dünya Örneği: Kitap Kataloğu
Tüm öğrendiklerimizi birleştiren bir örnek yapalım:
class Book:
"""Bir kitabı temsil eden sınıf."""
total_books = 0 # Class attribute
def __init__(self, title, author, pages, isbn):
self.title = title
self.author = author
self.pages = pages
self.isbn = isbn
self.is_available = True
Book.total_books += 1
def borrow(self):
"""Kitabı ödünç alır."""
if self.is_available:
self.is_available = False
return f"'{self.title}' ödünç alındı."
return f"'{self.title}' şu an müsait değil."
def return_book(self):
"""Kitabı iade eder."""
self.is_available = True
return f"'{self.title}' iade edildi."
def get_summary(self):
"""Kitap özetini döner."""
status = "Müsait" if self.is_available else "Ödünç verilmiş"
return f"{self.title} — {self.author} ({self.pages} sayfa) [{status}]"# Kullanım
book1 = Book("Python Crash Course", "Eric Matthes", 544, "978-1593279288")
book2 = Book("Clean Code", "Robert C. Martin", 464, "978-0132350884")
print(book1.get_summary())
# Python Crash Course — Eric Matthes (544 sayfa) [Müsait]
print(book1.borrow())
# 'Python Crash Course' ödünç alındı.
print(book1.borrow())
# 'Python Crash Course' şu an müsait değil.
print(book1.return_book())
# 'Python Crash Course' iade edildi.
print(f"Toplam kitap: {Book.total_books}") # Toplam kitap: 2Bu örnek basit ama OOP'nin gücünü gösteriyor:
Her kitap kendi verisini taşıyor (encapsulation).
Kitap ödünç alma/iade mantığı sınıfın içinde (organizasyon).
Yeni bir kitap eklemek tek satır (
Book(...)) kadar kolay (tekrar kullanılabilirlik).
Sınıf Tasarım İpuçları
Kendi sınıflarını yazarken şu kurallara uy:
İsimlendirme
Sınıf adları PascalCase:
StudentRecord,BankAccountMetod ve attribute adları snake_case:
get_balance,is_active"Private" özellikler alt çizgiyle başlar:
_internal_data
Tek Sorumluluk
Her sınıf tek bir şeyi iyi yapmalı. StudentDatabaseEmailerPDFGenerator gibi bir sınıf gördüysen, bir şeyler yanlış gidiyor demektir.
# Kötü — çok fazla sorumluluk
class Student:
def calculate_gpa(self): ...
def send_email(self): ...
def generate_pdf(self): ...
def connect_to_database(self): ...
# İyi — her sınıf tek sorumluluk
class Student:
def calculate_gpa(self): ...
class EmailService:
def send_email(self, student): ...
class ReportGenerator:
def generate_pdf(self, student): ...Docstring Yaz
class Rectangle:
"""Bir dikdörtgeni temsil eder.
Attributes:
width: Dikdörtgenin genişliği.
height: Dikdörtgenin yüksekliği.
"""
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
"""Dikdörtgenin alanını hesaplar."""
return self.width * self.heightYaygın Hatalar ve Tuzaklar
1. self'i Unutmak
class Broken:
def greet(): # self yok!
return "Merhaba"
b = Broken()
# b.greet() # TypeError: greet() takes 0 positional arguments but 1 was givenInstance metodu yazarken ilk parametre her zaman self olmalı. Python, nesne üzerinden metod çağrıldığında nesneyi otomatik olarak ilk argüman olarak geçirir.
2. Mutable Class Attribute Tuzağı
class Wrong:
items = [] # Tehlike! Tüm nesneler aynı listeyi paylaşır!
def add(self, item):
self.items.append(item)
a = Wrong()
b = Wrong()
a.add("x")
print(b.items) # ['x'] — Sürpriz! b'ye de eklendi!Mutable (değiştirilebilir) değerleri class attribute olarak tanımlama. Bunları __init__ içinde instance attribute olarak tanımla:
class Right:
def __init__(self):
self.items = [] # Her nesnenin kendi listesi
def add(self, item):
self.items.append(item)
a = Right()
b = Right()
a.add("x")
print(b.items) # [] — Doğru! Her nesne bağımsız.⚠️ Dikkat:
list,dict,setgibi mutable değerleri asla class attribute olarak kullanma. Her nesne aynı objeyi paylaşır ve bir nesnede yapılan değişiklik tüm nesneleri etkiler. Her zaman__init__içinde tanımla.
3. Sınıf Adı ve Değişken Adı Çakışması
# Kötü
str = "hello" # Built-in str sınıfını ezdik!
# str(42) # TypeError! Artık str fonksiyon değil, bir string.
# Değişken adlarında built-in isimleri kullanma
# list, dict, set, type, id, input, print, ...Ne Zaman Sınıf Yazmalısın?
Her şeyi sınıf yapmak zorunda değilsin. İşte karar rehberi:
Sınıf kullan:
Birbiriyle ilişkili veri ve davranışları gruplamak istiyorsan
Aynı yapıda birden fazla nesne oluşturacaksan
Nesnenin bir durumu (state) varsa ve bu durum değişiyorsa
Sınıf kullanma:
Sadece birkaç fonksiyonu gruplamak istiyorsan (modül kullan)
Durumu olmayan utility fonksiyonlar için (düz fonksiyon yeterli)
Tek bir instance olacaksa ve durumu yoksa (fonksiyonlar + sözlük yeterli)
# Buna sınıf gerekmez
class MathUtils:
@staticmethod
def add(a, b):
return a + b
# Bu yeterli
def add(a, b):
return a + b💡 İpucu: Python'da "her şeyi sınıf yap" yaklaşımı (Java tarzı) pek benimsenmez. Python'da fonksiyonlar birinci sınıf vatandaştır ve çoğu zaman yeterlidir. Sınıfı gerçekten ihtiyacın olduğunda kullan.
Alıştırma: Kendi Sınıfını Yaz
Şimdi öğrendiklerini pekiştirmek için basit bir Playlist sınıfı yaz:
class Playlist:
"""Müzik çalma listesi."""
def __init__(self, name):
self.name = name
self.songs = []
def add_song(self, song):
"""Listeye şarkı ekler."""
if song not in self.songs:
self.songs.append(song)
return f"'{song}' eklendi."
return f"'{song}' zaten listede."
def remove_song(self, song):
"""Listeden şarkı çıkarır."""
if song in self.songs:
self.songs.remove(song)
return f"'{song}' çıkarıldı."
return f"'{song}' listede bulunamadı."
def show(self):
"""Çalma listesini gösterir."""
if not self.songs:
return f"'{self.name}' boş."
header = f"🎵 {self.name} ({len(self.songs)} şarkı):"
songs = "\n".join(f" {i+1}. {s}" for i, s in enumerate(self.songs))
return f"{header}\n{songs}"
# Test
playlist = Playlist("Favori Şarkılarım")
print(playlist.add_song("Bohemian Rhapsody"))
print(playlist.add_song("Stairway to Heaven"))
print(playlist.add_song("Hotel California"))
print(playlist.add_song("Bohemian Rhapsody")) # Zaten var
print()
print(playlist.show())Çıktı:
'Bohemian Rhapsody' eklendi.
'Stairway to Heaven' eklendi.
'Hotel California' eklendi.
'Bohemian Rhapsody' zaten listede.
🎵 Favori Şarkılarım (3 şarkı):
1. Bohemian Rhapsody
2. Stairway to Heaven
3. Hotel CaliforniaÖzet
OOP, gerçek dünyayı nesnelerle modelleme yaklaşımıdır. Veri ve davranışı bir arada tutar.
Sınıf (class) bir şablon, nesne (object/instance) o şablondan üretilen somut bir örnektir — kurabiye kalıbı ve kurabiye gibi.
classkeyword ile sınıf tanımlanır, sınıfı çağırarak (MyClass()) nesne üretilir.Class attribute tüm nesneler tarafından paylaşılır, instance attribute her nesneye özeldir.
Python'da her şey bir nesnedir — sayılar, stringler, listeler, fonksiyonlar, hatta sınıfların kendisi.
OOP'nin 4 prensibi: Encapsulation (kapsülleme), Inheritance (kalıtım), Polymorphism (çok biçimlilik), Abstraction (soyutlama).
dir()ile nesnenin tüm özelliklerini,type()ile tipini,id()ile kimliğini öğrenebilirsin.
AI Asistan
Sorularını yanıtlamaya hazır