Beyin Fırtınası - Nesne Tabanlı Programlama Bize Neler Katar?

Paylaştığım linkte güzel bir cevap var.

Hatta şuraya da bakılabilir.

4 Beğeni

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.

4 Beğeni

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.”

2 Beğeni

İş 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.

2 Beğeni

+1


Estağfurullah ne yanlış anlaması :slight_smile:

Sanırım yanlış bildiğim nokta burası. Bu yüzden olsa gerek ortalığı galeyana getirdim galiba :slight_smile: . 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

1 Beğeni

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

1 Beğeni

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ı?

1 Beğeni

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')};
1 Beğeni

@tevhidulvahset burada mesela iyi incele örneği

subtype polymorphism

parametric polymorphism

ad-hoc polymorphism


7 Beğeni

@aib saolun hafızamı tazelediniz :smiley:
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?

5 Beğeni

Cevabını vermişsiniz zaten hocam. Encapsulation :slight_smile:

1 Beğeni

Yanlış mı anlıyorum bilmiyorum ama benim subtype polymorphism ile anladığım şey, nesnenin başka bir nesne gibi davranmasından ziyade parent classtan miras alınan metodun child classlarda override edilmesiyle metodun yaptığı işlemin değiştirilmesi.

1 Beğeni

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?

1 Beğeni

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:

1 Beğeni

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…

2 Beğeni

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.

1 Beğeni