Jump to page: 1 2
Thread overview
D Haftanın Sorusu
Jul 18, 2009
erdem
Jul 19, 2009
esatarslan52
Jul 19, 2009
esatarslan52
Jul 19, 2009
erdem
Jul 19, 2009
esatarslan52
Jul 19, 2009
erdem
Jul 19, 2009
erdem
Jul 20, 2009
erdem
Jul 20, 2009
erdem
Jul 20, 2009
erdem
Jul 20, 2009
quasimodo
Sep 24, 2012
mert
July 18, 2009

Hem forumlarda hareketliliği arttırmak açısından, hem fikir jimnastiği olması açısından hem de D dilini öğrenirken konunun ilginç ayrıntılarının ortaya çıkması açısından böyle bir soru hazırladım. Sizin de böyle sorularınız varsa buraya yazın lütfen.

Kurucusu aşağıdaki şekli çizen YatayÇizgi isminde bir sınıf tanımlayın

'+----------+'

sınıfın kurucu işlevine - işaretlerinin sayısı argüman olarak geçiliyor.

class YatayÇizgi
{
   this (int n)
   {
        /+  ... +/
   }
}

Benzer şekilde DikeyÇizgi sınıfı tanımlayın o da bu şekilde bir yatay çizgi çizsin: 'Gene burada '|' sayısını (çizginin yüksekliğini) parametre olarak DikeyÇizgi sınıfının kurucu işlevine geçiyoruz'

'|
|
|
|
'
Bir tane Çerçeve isminde (gömülü olarak) üst yatay çizgiyi, dikey çizgiyi ve alt yatay çizgiyi içeren bir sınıf tasarlayın. Kurucusu iki tane argüman alacak, çerçevemizin genişlik ve yüksekliğini

class Çerçeve
{
   this (int genişlik, int yükseklik)
}

Çerçeve nesnesini şu şekilde oluşturabilmeliyiz.

'Çerçeve çerçeve = new Çerçeve (5, 2);'

Yukardaki örnekte oluşturduğumuz çerçeve nesnesi ekrana şu çıktıyı verecek:

'
+-----+
|
|
+-----+'

Not : Bu sorunun cevabını bildiğini bildiğim için Ali bey bu soruyu yanıtlamasın lütfen :) En sonunda konunun ayrıntılarını anlatsın. Bize yeni soru hazırlayabilirse, ya da soru ve cevaplardaki olası eksiklikleri, hataları gösterebilirse seviniriz..

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

July 19, 2009
import std.stdio;

class YatayÇizgi
{
   public:
       int sayi;
       this(int pSayi)
       {
           sayi = pSayi;
           yatayÇiz();
       }
       void yatayÇiz()
       {
           write("+");
           for (int i =0;i<sayi;i++)
               write("-");
           writeln("+");
       }
};
class DikeyÇizgi
{
   public:
       int sayi;
       this(int pSayi)
       {
           sayi = pSayi;
           dikeyÇiz();
       }
       void dikeyÇiz()
       {
           for (int i =0;i<sayi;i++)
               writeln("|");
       }
};

class ÇerçeveÇiz
{
   public:
       this(int pGenişlik,int pYükseklik)
       {
           yatayÇizgi1 = new YatayÇizgi(pGenişlik);
           dikÇizgi = new DikeyÇizgi(pYükseklik);
           yatayÇizgi2 = new YatayÇizgi(pGenişlik);
       }
   private:
       YatayÇizgi yatayÇizgi1;
       DikeyÇizgi dikÇizgi;
       YatayÇizgi yatayÇizgi2;
};

int main()
{
   ÇerçeveÇiz çerçe = new ÇerçeveÇiz(5,5);

   return 0;
}

Benim çözümüm bu şekilde.
Diğer bi yöntem olarak YatayÇizgi ve DikeyÇizgi sınıfınlarını miras alarak yapmaktı. Fakat çoklu miras ta iki sınıfın birden ilklemesini nasıl yapacağımı bulamadım. Tekli mirasta super() fonksiyonu ile bunu yapa biliyoruz fakat çoklu mirasta nasıl bir yöntem izlememiz lazım ?

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

July 19, 2009

http://www.digitalmars.com/d/archives/digitalmars/D/learn/Multiple_Inheritance_Mixins_and_Constructors_16628.html

Burdaki örnekte bir class'ı ve interface'i aynı anda miras olarak almış. Ben bunu iki class için denediğim de de "ikinci interface olmalı" gibisinden hata veriyo. Interface tam olarak ne amaçla kullanılıyo onu anlamadım açıkcası.

Bir de c++ da olduğu gibi sınıf içinde fonksiyonun deklare edip sınıf dışında işlevini yazmak istedim fakat bir türlü başaramadım. Örneğin yatayÇiz() ve dikeyÇiz() fonksiyonlarını c++ da olduğu gibi sınıf dışında YatayÇiz::yatayÇiz() şeklinde ifade edip işlevini yazmam mümkün mü? Sitesinde aradım fakat her hangi birşey bulamadım.

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

July 19, 2009

Evet çözüm doğru! Süper :)

Hatta dikeyÇiz() ve yatayÇiz() işlevlerine gerek kalmadan biraz daha kısaltırsak:



import std.stdio;

class YatayÇizgi
{
   this (int n)
   {
       write ("+");
       for (int i = 0; i < n; ++i)
       {
           write ("-");
       }
       writeln ("+");
   }
}

class DikeyÇizgi
{
   this (int n)
   {
       for (int i = 0; i < n; ++i)
       {
           writeln ("|");
       }
   }

}

class Çerçeve
{
   YatayÇizgi ust_;
   DikeyÇizgi orta_;
   YatayÇizgi alt_;

   this (int genişlik, int yükseklik)
   {
       ust_ = new YatayÇizgi (genişlik);
       orta_ = new DikeyÇizgi (yükseklik);
       alt_ = new YatayÇizgi (genişlik);
   }

}

void main ()
{
   Çerçeve çerçeve = new Çerçeve (12,5);
}


D bildiğim kadarıyla çoklu kalıtımı (multiple inheritance) desteklemiyor diye biliyorum. Buradaki ilişki (has-a) sahip olma ilişkisi. Yani Çerçeve nesnesi YatayÇizgi ve DikeyÇizgi nesnelerinden oluşuyor..

Not : Bu soruları orjinal olarak ben oluşturmadım. Bir C++ kitabından aldım. D için şimdilik kaynak olmadığı için ben de C++ örneklerini D'ye geçiriyorum. Böylelikle dilin yapısını öğrenmede biraz daha kolaylık sağlıyor

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

July 19, 2009

Interface'in özellikleri bana C++ daki soyut sınıfları çağrıştırdı.

Çoklu mirastaki amacım yatayÇiz() ve dikeyÇiz() fonksiyonlarını tekrar yazmadan yeni sınıfa aktarmaktı.

int ABC::func() gibi bir kullanım bana daha düzenli ve kod okuması daha kolay geldiği için D'de de olmasını tercih ederdim. Böyle bir yapının olmamasının Modüler bir yapısı olmasıyla bir ilgisi olabilir mi ki acaba <_<

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

July 19, 2009

Alıntı (esatarslan52):

>

http://www.digitalmars.com/d/archives/digitalmars/D/learn/Multiple_Inheritance_Mixins_and_Constructors_16628.html

Burdaki örnekte bir class'ı ve interface'i aynı anda miras olarak almış. Ben bunu iki class için denediğim de de "ikinci interface olmalı" gibisinden hata veriyo. Interface tam olarak ne amaçla kullanılıyo onu anlamadım açıkcası.

Çoklu kalıtımla ilgili söylediğimi düzeltiyorum. D çoklu kalıtımı şu şekilde destekliyormuş:
Alıntı:

>

'D'nin nesne yönelimliliği Java ve C#'ınkine benzer: gerçekleştirme olarak tekli, arayüz olarak çoklu kalıtım... '

class GereçÜstSınıfı { ... }
class Alet { ... }
class Gereç : GereçÜstSınıfı, Arayüz1, Arayüz2
{
   Alet Alet_döndür() { ... }
   alias Alet_döndür this;  // Gereç Alet'ten türemiş olur
}

Bu kısmı da Andrei Alexandrescu'nun Neden D makalesi (http://ddili.org/makale/neden_d.html) Nesne Yönelimli Olanaklar kısmından aldım.

Bir de C++'den hatırladığım kadarıyla çoklu kalıtım o kadar yaygın olarak kullanılmaz. Genelde kütüphane içlerinde ve kullanımı azdır. Belki ne yapmaya çalıştığını ve yazdığın örnek kodu yazarsan çoklu kalıtıma gerek duymayan bir çözüm bulabiliriz.

Arabirimler (interfaces) benim için de yeni bir kavram..

Arabirimler bir dizi işlevden oluşuyor. Arabirimler sınıflardan türetilemiyor, sadece diğer arabirimlerden türetiliyor. Bir sınıf bir arabirimi birden fazla devralamıyor.

interface D
{
   void foo();
}

class A : D, D	// hata
{
}

Bir arabirime ait bir örnek (nesne) oluşturamıyoruz.

interface D
{
   void foo();
}

..

D d = new D();		// hata, bir arabirime ait örnek oluşturulamaz

Bir arabirime ait üye işlevde gerçekleştirmeye izin verilmiyor.

interface D
{
   void bar() { }	// hata, gerçekleştirmeye izin verilmez.
}

Arabirimin gerçeklemesini bu arabirimden devralan sınıflarda tanımlıyormuşuz:

interface D
{
   void foo();
}

class A : D
{
   void foo() { }	// tamam gerçekleşmeyi sağlıyor
}

class B : D
{
   int foo() { }	// hata, void foo() şeklinde bir gerçekleme değil
}

Arabirimle ilgili konunun tamamı da bu adreste: http://www.digitalmars.com/d/1.0/interface.html

Alıntı (esatarslan52):

>

Bir de c++ da olduğu gibi sınıf içinde fonksiyonun deklare edip sınıf dışında işlevini yazmak istedim fakat bir türlü başaramadım. Örneğin yatayÇiz() ve dikeyÇiz() fonksiyonlarını c++ da olduğu gibi sınıf dışında YatayÇiz::yatayÇiz() şeklinde ifade edip işlevini yazmam mümkün mü? Sitesinde aradım fakat her hangi birşey bulamadım.

C++'de genelde kullandığımız sınıf ve işlevlerin bildirimleri bir başlık dosyasına (.h uzantılı bir dosya) gidiyordu. Bunların tanımları da bir kaynak dosyasına (.c uzantılı bir dosya) (cpp,cc vs.. ) gidiyordu. Bunu da biz derleyici için yapıyorduk. Artık üye işlevlerin, statik üyelerin ayrı olarak bildirilmesine gerek olmadığı ve:

int ABC::func() { return 7; }
int ABC::z = 7;
extern int q;

gibi bir yazım şekline ihtiyaç kalmadığını söylüyor. Buradan ben D'de böyle bir şeye ihtiyaç kalmadığı için olmadığı anlamı çıkarıyorum. Tam olarak adresi de bu:

http://www.digitalmars.com/d/1.0/overview.html <-- Declaration vs Definition kısmında

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

July 19, 2009

Alıntı (esatarslan52):

>

Interface'in özellikleri bana C++ daki soyut sınıfları çağrıştırdı.
Evet saf soyut sınıflarda da (pure virtual class) sınıfa ait bir örnek oluşturamıyorduk. Anladığım kadarıyla D çoklu kalıtımı arayüzler kullanarak destekliyor. Alttaki örnekte olduğu gibi C++ stili iki ayrı sınıftan tek bir sınıf devralmayı desteklemiyor.

Ama C++'deki soyut sınıfları
Alıntı (esatarslan52):

>

Çoklu mirastaki amacım yatayÇiz() ve dikeyÇiz() fonksiyonlarını tekrar yazmadan yeni sınıfa aktarmaktı.

Aslında burada çoklu mirasa ihtiyaç duyacak bir durum yok. Hatta bu işlevlere gerek de yok. Çünkü zaten YatayÇizgi ve DikeyÇizgi sınıflarının kurucu işlevleri bu işlemi yapıyor. Eğer çerçeve sınıfı yatay ve dikey çizgilerden oluşur. Diyebiliyorsak burada bir sahip olma (has-a) ilişkisi vardır. Ya da şöyle bir örnek: "Bir kuşun kanadı vardır". Gene aynı şekilde buradaki ilişki de sahip olma ilişkisi oluyor.

class Kus : public Hayvan
{
     Kuyruk kuyruk_;

/* ... */
};

Çoklu kalıtım ise bir sınıfın birden fazla sınıfın özelliklerini devralması ile oluşuyor:

class A { ... };
class B { ... };

class C : A , B { ... };

Yani C sınıfı hem A'dır hem B'dir anlamına geliyor. Sanırım Ali beyin bu konuyla ilgili 'Balina hem memelidir hem de balıktır' gibi bir örneği vardı. Ancak uygulamasını aradan uzun zaman geçtiği için hatırlayamıyorum.

Alıntı (esatarslan52):

>

int ABC::func() gibi bir kullanım bana daha düzenli ve kod okuması daha kolay geldiği için D'de de olmasını tercih ederdim. Böyle bir yapının olmamasının Modüler bir yapısı olmasıyla bir ilgisi olabilir mi ki acaba <_<

Aslında kesin olup olmadığı konusunda bir şey söyleyemeyeceğim. Çünkü D konusunda hala çok az kaynağa sahibiz. Biraz önce de bahsettiğim gibi "Artık üye işlevlerin, statik üyelerin ayrı olarak bildirilmesine gerek olmadığı söyleniyor." Buradan da ben ihtiyaç kalmamışsa kullanılmıyordur diye düşünüyorum.

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

July 20, 2009

Alıntı (acehreli):

>

Nesne yönelimli programlamada doğru kalıtımın büyük bir çoğunluğu arayüz kalıtımıdır. Örneğin Şekil sınıfının çiz() diye bir üyesi olduğu duyurulur, ve kullanıcılar Şekil türünden nesneleri 'nesne.çiz()' diye kullanabilirler. Gerçek türlerini bilmeden...

Benim de karşıma çoğunlukla böyle sıradüzenler çıkar (basitlik ön planda! :) ): Arayüz sınıfı, ve onu gerçekleştiren alt sınıflar. Çok temiz bir tasarımdır...

Süpermiş! :)

Bir de rica etsek Esat'ın sorduğu çoklu kalıtıma örnek verebilirmisiniz. Benim aklımda sadece pek yaygın olarak kullanılmadığı kalmış. CDili'nin eski mesajlarına da baktım ama bulamadım. Bir de bir yerlerden bir balina :) örneği kalmış ama tam hatırlayamadım. Açıkçası bende D'de çoklu kalıtımın gerçekleştirmesini nasıl yaptığımızı merak ediyorum.

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

July 20, 2009

Alıntı (quasimodo):

>

D dilinde çoklu kalıtım var mı ki? Yok diye biliyorum.

Hehe! Yeni kalktın galiba :) Dünden beri bunu konuşuyoruz.

Alıntı (erdem):

>

Çoklu kalıtımla ilgili söylediğimi düzeltiyorum. D çoklu kalıtımı şu şekilde destekliyormuş:
Alıntı:

>

'D'nin nesne yönelimliliği Java ve C#'ınkine benzer: gerçekleştirme olarak tekli, arayüz olarak çoklu kalıtım... '

> class GereçÜstSınıfı { ... }
> class Alet { ... }
> class Gereç : GereçÜstSınıfı, Arayüz1, Arayüz2
> {
>     Alet Alet_döndür() { ... }
>     alias Alet_döndür this;  // Gereç Alet'ten türemiş olur
> }
> ```

>
> Bu kısmı da Andrei Alexandrescu'nun Neden D makalesi (<http://ddili.org/makale/neden_d.html>) Nesne Yönelimli Olanaklar kısmından aldım.
>

Aslında doğru D, C++'den alıştığımız  iki ayrı sınıftan tek bir sınıf devralma olayını desteklemiyor.  Ama  bir sınıf ve birden fazla arayüz kullanarak çoklu kalıtımı destekliyor.

-- 
[ Bu gönderi, <http://ddili.org/forum>'dan dönüştürülmüştür. ]
July 19, 2009

Ben de başka zamanlarda da yaptığım gibi, başka olanakları da kullanalım diye gereksizce :) aşağıdaki gibi yazdım. Yeni olarak şunları kullandım:

   interface: arayüz
   repeat: tekrarlayarak string oluşturan bir fonksiyon
   foreach ve 0..n gibi bir aralık
   appender: "sonuna ekleyen" bir tür
   foreach ve dizi

erdem, soruda öyle istenmediğini biliyorum ama ben yine de esatarslan52'nin yaptığı gibi ayrı 'çiz()' fonksiyonları kullanacağım. Çünkü normalde kurucunun kullanılabilir bir nesne oluşturması yararlı olur. Ondan sonra onunla istediğimizi yaparız.

Öyle olmasaydı, aşağıda 'şekiller_''i baştan oluşturup sonra kullanamazdık.

import std.stdio;
import std.string;
import std.array;

interface Şekil
{
   void çiz();
}

class YatayÇizgi : Şekil
{
   int genişlik_;

   this (int n)
   {
       genişlik_ = n;
   }

   void çiz()
   {
       writeln(repeat("-", genişlik_));
   }
}

class DikeyÇizgi : Şekil
{
   int yükseklik_;

   this (int n)
   {
       yükseklik_ = n;
   }

   void çiz()
   {
       foreach(i; 0..yükseklik_) {
           writeln('|');
       }
   }
}

class Çerçeve : Şekil
{
   Şekil[] şekiller_;

   this (int genişlik, int yükseklik)
   {
       şekiller_ = new Şekil[0];

       auto sonuna_ekleyici = appender(&şekiller_);
       sonuna_ekleyici.put(new YatayÇizgi(genişlik));
       sonuna_ekleyici.put(new DikeyÇizgi(yükseklik));
       sonuna_ekleyici.put(new YatayÇizgi(genişlik));
   }

   void çiz()
   {
       foreach(şekil; şekiller_) {
           şekil.çiz();
       }
   }
}

void main ()
{
   Çerçeve çerçeve = new Çerçeve(12,5);
   çerçeve.çiz();
}

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

« First   ‹ Prev
1 2