Paylaştığım linkte güzel bir cevap var.
Hatta şuraya da bakılabilir.
Paylaştığım linkte güzel bir cevap var.
Hatta şuraya da bakılabilir.
OOP açısından bakarsak, bir alt sınıf miras aldığı üst sınıfın ilgili metotlarını farklı işler yapacak şekilde gerçekleştiriyorsa(yukarıda logger örneği verildi) burada polimorfizm var.
ILogger logger = new DatabaseLogger(); // istesek FileLogger kullanırdık
logger.log();
Ama duck typing bildiğim kadarıyla elinizdeki nesnelerin belirli bir metodu olduğundan emin olduğunuz bir gerçekleştirim. Miras alma yok. Çok çeşitlilik yok(yani aynı amaca hizmet eden bir sınıftan türememiş). Sadece yapacağımız iş için gerekli metoda sahip mi değil mi ona bakıyoruz. Mesela elimizdeki veri tipinin uzunluğunu almak istiyorsak Python’da __len__
özel metoduna sahip olması gerekir. Gibi gibi.
Benim okuduğum kaynaklara göre polimorfizm
için illa ki miras alma zorunluluğu yok. Yani duck typing’e göre bir fonksiyonu yazacaksak, aslında bir yerde o fonksiyonu polimorfik hale de getirmiş oluyoruz diye düşünüyorum. Okuduğum yorumlara göre şöyle bir tanımlama vardı, “duck typing, kendi başına bir polimorfizm değil kısıtlanmış bir polimorfizmdir.”
İş ilanlarında öyle bir şey aranmıyor.
Yukarıdaki fonksiyonda argüman olarak verilecek nesnelerin __add__
isimli bir metodu olduğu varsayılıyor ve bu metot varsa x + y
işleminin gerçekleşmesini istiyoruz. Fonksiyon sadece bu if
satırından oluşsaydı, fonksiyonu duck typing
’e göre dizayn etmiş olurduk ama yine de polimorfizme benzediğini görüyoruz.
Diğer if
satırında ise, nesnenin __add__
metodu olmamasına rağmen, __add__
ile yapılan işlemin dict
nesnesine de uygulanabilir olduğunu düşündüğümüz için, o nesnenin __add__
'in yaptığı işleme benzediğini düşündüğümüz bir fonksiyonunu -yani update
isimli fonksiyonu- kullanıyoruz ve topla
fonksiyonumuz benzer işlemleri farklı yollardan yapan ortak bir arayüz haline gelmiş oluyor.
Yanılıyorsam lütfen düzeltin.
+1
Estağfurullah ne yanlış anlaması
Sanırım yanlış bildiğim nokta burası. Bu yüzden olsa gerek ortalığı galeyana getirdim galiba . Ben polymorphismi yanlış mı biliyorum anlamadım.
Örneğin :
class Base():
def log(msg):
print("Logged : ", msg)
def debug_level(msg):
print("Debug level", msg)
class ConsoleLog(Base):
def __init__(self):
pass
class FileLog(Base):
def __init__(self):
pass
FileLog.log("File")
ConsoleLog.log("console")
yukarıdaki kodlarda yer alan Base class üzerinden aslında console ve file logger claslarına hiçbir ekleme yapmadan kullanabiliyoruz.
Base clasa ne eklersek onu alt sınıflara otomatik olarak eklemiş oluyoruz. Şimdi farzedelimki bircok alt sınıf var. Bunların hepsiyle uğraşmak yerine ana class (base class) üzerinden yönetmek ve yeni bir özellik eklemek daha kolay ve anlaşılır olmazmı? İşte ben bunu polymorphism olarak biliyorum.
Yanlışım var ise düzeltin lütfen
c# da fln generic diye geçiyor sanırım
c++ da templateler var daha kullanışlı bence
tamamlama fln da yapabiliyorsun
template<typename t, int size>
class Foo
{
private:
sp::Map arr[size];
public:
Foo();
};
gibi
bunu mesela
Foo<float,10> foo;
diye initialize ettiğimizde
class Foo
{
private:
sp::Map arr[10];
public:
Foo();
};
gibi initialize ediyor…bu templateyi kullanarak initialize ediyor
bahsi geçen bu yaklaşım öğrenilmesi gereken bir konu mu? Hiç fikrim yok ve OOP anlatan takip ettiğim kaynaklarda böyle bir şeye denk gelmedim. Ya da bu bir tabir mi? Yoksa programlamaya özel bir yapı mı?
kısaca bir işlemi tiplere göre genelleştirme diyebiliriz sanırım
bir işlemi çoklu tiplerle yapma
mesela cpp de
template<typename T>
const T& max(const T& x, const T& y) // parametric polymorphism
{
...
}
// Bunu int ile çağırmak istiyorum diyelim
int var{max(10,12)};
// Bunu float ile çağırmak istiyorum diyelim
float var{max(10.f,12.f)};
// Bunu double ile çağırmak istiyorum diyelim
double var{max(10.0,12.0)};
// Bunu char ile çağırmak istiyorum diyelim
char var{max('a','z')};
@tevhidulvahset burada mesela iyi incele örneği
subtype polymorphism
parametric polymorphism
ad-hoc polymorphism
@aib saolun hafızamı tazelediniz
Ve yeni şeyler öğrendim sayenizde
Hem datayi hem kodu baska insanlara belirli bir kontratta (public ve protected interface’ler) verebilmek.
Disariyi icerden ayirmak. (Encapsulation sanirim) Objenin her zaman belirli, kararli bir state’te olmasi. Istenen ozelliklerin (invariant) korunabilmesi.
Dogru tasarimli bir sinif verilen caylagin o sinifi bozamamasi, objelere ters is yaptiramamasi. Dogru tasarim verilen bir caylagin hatalarinin iceride kalmasi. (Yine encapsulation sanirim.)
Baska paradigmalari kullanmis, karsilastirabilecek insanlarla konusmanizi tavsiye ederim. Bir de karsi tarafin nereden geldigini bilin: Tek tabanca calismaya alismis bir insan ile isi UML diyagramlari cizmek olan insana farkli seyler ifade eder.
Degiskenin scope’unu ne kadar sinirlarsan o kadar iyi. Birbirlerine gobekten bagli (tightly coupled) fonksiyonlar degisken paylasacaksa, bu degisken icin fonksiyondan daha buyuk ama globalden ve paketten/modulden daha kucuk scope sunuyor: sinif.
Bu paradigmadan bagimsiz bir sey. Spaghetti koddan kurturmak isteyen programci bir yolunu bulur. Istemeyen de yapmanin bir yolunu.
Hangi veriyi, nasil ve neye karsi guvende tutmaktan bahsediyoruz?
Cevabını vermişsiniz zaten hocam. Encapsulation
Yanlış mı anlıyorum bilmiyorum ama benim subtype polymorphism
ile anladığım şey, nesnenin başka bir nesne gibi davranmasından ziyade parent class
tan miras alınan metodun child class
larda override
edilmesiyle metodun yaptığı işlemin değiştirilmesi.
Nesnenin baska bir nesne gibi davranmasindan kasit nedir peki?
Muhtesem soyut konusuyoruz, muhtesem genis anlami olan bir kelimenin tanimini yere oturtmamiz zor.
Ikinci soyledigin seyin ismini kendin verdin (override) gibi geliyor ama. Inheritance’i manali kilan sey. o da subtyping’in bir yontemi degil mi?
Bu arada bu cümleyi kullanan kişi ben değilim. Ben de bu söz ile neyin kast edildiğini merak ettim. Çünkü bu ifadeden ben başka bir şey anlıyorum. Mesela bu cümleyle ifade edilen şey bana göre belli bir sınıfın özel yapısına ihtiyaç duyan bir işlem için, o sınıfı taklit edebilen başka bir sınıfın oluşturulması anlamına geliyor.
Hemen basit bir örnek göstereyim:
import sys
import tkinter as tk
root = tk.Tk()
text = tk.Text(master=root)
text.pack()
button = tk.Button(
master=root,
text="Yaz",
command=lambda: print("hello")
)
button.pack()
sys.stdout = text
root.mainloop()
Yukarıdaki kodları çalıştırdığımızda karşımıza çıkan ekrandaki Yaz
düğmesine tıkladığımızda şöyle bir hata almamız gerekiyor.
AttributeError: 'Text' object has no attribute 'write'
Ama biz sys.stdout
nesnesini taklit eden yani sys.stdout
nesnesi gibi davranan bir sınıf tanımlarsak, bu sorunu çözebiliriz.
import sys
import tkinter as tk
class StdOutRedirector:
def __init__(self, widget):
self.widget = widget
def write(self, string):
self.widget.insert("end", string)
root = tk.Tk()
text = tk.Text(master=root)
text.pack()
button = tk.Button(
master=root,
text="Yaz",
command=lambda: print("hello")
)
button.pack()
sys.stdout = StdOutRedirector(text)
root.mainloop()
Burada StdOutRedirector(text)
ifadesi, tk.Text
nesnesinin, stdout
olarak kullanılmasına olanak sağlar.
Bu yüzden bir nesnenin başka bir nesne gibi davranması
sözünden, yukarıdaki örnekle anlatmaya çalıştığım şeyi anlıyorum.
Tamam kendim verdim ama senin linkini verdiğin wikipedia adresindeki örnek zaten subtyping polymorphism başlığı altında veriliyor. Dolayısıyla o örnekte override
edilmiş bir metod var. Ve o örneği görünce de aklıma doğal olarak şunları söylemek geldi:
Bence nesne yönelimli programlamanın programlama alanına kattığı en güzel işlevselliklerden birisi de GUI tasarlama ortamlarının gelişmesi.
Ortama sürüklediğimiz butonlar, textbox’lar vs. tamamı bir nesne, bu nesnelerin her birinin attribute (nitelikleri, örneğin butonun adı), methodları (örneğin butonun tıklama olayında ne yapacağı), o nesneye özel. Yani OOP mantığı ile çalışan GUI tasarımcılarında forma eklediğiniz buton vb. şeylerin her biri kendi türünün sınıfından örneklenen nesneler. Örneklendikleri sınıflar bu nesnenin hangi özelliklere sahip olacağını, hangi görevleri yerine getirebileceklerini (kalıplarını) belirliyor.
Bu kullanım biçimi GUI tasarım araçları gibi programcının da işini kolaylaştırıyor.
İş hayatında soruyorlar mı bilmem fakat üniversitede çalışmak isteyen çok yakın bir arkadaşıma sözlü mülakatta OOP mantığının ne olduğunu örnek vererek anlatmasını istemişlerdi.
Elimdeki bir çok kitapta OOP ünitesinde yazar, bu soyut kavramı açıklamaya çalışmış; lakin o bölümleri ilk okuduğumda çok da birşey anlamamıştım. Esasında faydasını anlamak için bol bol kodlamak lazım. O zaman olay daha iyi anlaşılıyor. Sürekli yazılım geliştiren çok tecrübeli birisi değilim fakat hobi amaçlı ufak uğraşlarımda bile Class yapısının faydalarını gördüm.
Sizlerin bahsettiği çok biçimlilik, override, overload, kalıtım, kapsülleme vs. faydaları var. İstihza belgelerinde Fırat ÖZGÜL’ün dediği gibi kodların inci taneleri gibi düzenli görünmesini sağlıyor.
Ayrıca bence modüler tasarımın en önemli yapı taşı.
Güzel bir konu olmuş, okudukça öğreniyoruz. Hayat boyu öğrenme devam ediyor…
adapter veya wrapper
O zaman polymorphism ile alakasi yok. Veya olabilir ama daha fazla kafa yormayi reddediyorum.
Ben okumamistim, cunku dedigim gibi: Kullanisliligi genelliginde olan bir terimin spesifik tanimini aramakla vakit kaybetmek istemiyorum.
Ama bakinca Animal
’i extend eden Cat
ve Dog
goruyorum. Subtyping yani. Override edilen bir sey yok, olsa da fark etmez. Onemli olan Animal isteyen yerde Cat veya Dog kullanilabilmesi.