Forum: Ders Arası RSS
D sınıfları hakkında
Sayfa:  1  2  sonraki 
zafer #1
Üye Tem 2009 tarihinden beri · 700 mesaj · Konum: Ankara
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: D sınıfları hakkında
Merhaba,

D dilinde sınıf tanımı yaparken public, private gibi erişim belirteçlerini kullanabiliyormuyuz. Örneğin aşağıdaki kodda class önündeki public belirtecinin bir anlamı var mı?

public class BirSınıf
{
    public this()
    {
        // Ben bir kurucuyum, bu sınıftan oluşturulacak nesneyi
        // kullanım için hazırlarım.
    }
}

Diğer bir sorum, sınıfları türetilmeye karşı kapatabiliyormuyuz. Örneğin C# dilinde sealed olarak işaretlenen sınıflardan türetilme yapılamıyor. Böyle bir şey D sınıfları içinde mümkün mü?
https://github.com/zafer06 - depo
acehreli (Moderatör) #2
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
zafer:
aşağıdaki kodda class önündeki public belirtecinin bir anlamı var mı?

Evet, anlamı var ama o sınıfın nerede tanımlandığına bağlı. En dışarıda modül düzeyinde tanımlanmışsa bile, eğer kendisinde önce başka bir erişim belirteci varsa bu sınıfı modülün kullanıcılarına açar:

private:
 
// ... buradaki bütün tanımlar modüle özel ...
 
public class BirSınıf  // Bu sınıf kullanıma açık
{}
 
// ... buradakiler de özel 

Modül olarak söyledim ama bütün o kod başka bir sınıfın veya yapının içinde de olabilirdi.

sınıfları türetilmeye karşı kapatabiliyormuyuz

Bundan emin değildim. Evet, 'final' ile kapatılabiliyor:

class Üst
{}
 
final class Son : Üst
{}
 
class Türetemez : Son    // <-- Derleme hatası
{}
 
void main()
{}

'fina'l anahtar sözcüğü üye işlevlerin alt sınıflar tarafından tanımlanmasını da önler:

class BirSınıf
{
    final void foo()    // <-- Alt sınıflar anlamını değiştiremezler
    {}
}

Ali
Avatar
Salih Dinçer #3
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Hocam, hazır konu açılmışken; package {} olayını da bir irdeleyebilir miyiz?

Örneğin:

import std.stdio, std.string;
 
package {
    class Saat {
        int saat;
        int dakika;
        int saniye;
 
        this (int d, int s = 0)
        {
            this.saat = d/60;
            this.dakika = d%60;
            this.saniye = s;
        }
 
        override string toString() const
        {
            return format("%02s:%02s:%02s", saat, dakika, saniye);
        }
    }
  
    class Ortanca {
 
    }
 
    final class Sonuncu : Saat {
        this (int saat, int dakika, int saniye) {
            super(dakika + (saat * 60), saniye);
        }
    }
}
 
package {
    class deneme : Saat {
        this (int saat, int dakika, int saniye) {
            super(dakika + (saat * 60), saniye);
        }
    }
}
 
void main() {
    auto geceYarısı = new Saat(30);
    auto yenibirSaat = new Sonuncu(1, 23, 45);
    auto bozukSaat = new deneme (0, 0, 0);
 
    writeln(geceYarısı, "\n",
            yenibirSaat, "\n",
            bozukSaat
           );
}
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
acehreli (Moderatör) #4
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Modülün 'package' olarak işaretlenen olanakları bu pakedin diğer modüllerine de açıktır. Ama bunu deneyebilmek için birden fazla modül dosyası kullanmak gerek.

Örneğin, gösterdiğin kodu saat.d ismiyle kaydet. Aynı klasöre bir de takvim.d diye bir modül yerleştir. Şimdi saat.d ve takvim.d aynı pakede ait olurlar. takvim.d, saat.d içindeki 'package' olanaklarına erişebilir. Ama modül isimlerine pakedin ismini de yazmak gerekiyor.

Bu konular bana çok karışık gelmişti ama sonunda çalışan örnekler bulabilmiştim. Paket kavramı için:

  http://ddili.org/ders/d/moduller.html

Erişim hakları için:

  http://ddili.org/ders/d/sarma.html

Ali
zafer #5
Üye Tem 2009 tarihinden beri · 700 mesaj · Konum: Ankara
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #3
Salih Dinçer:
Hocam, hazır konu açılmışken; package {} olayını da bir irdeleyebilir miyiz?

Salih bu konuyu gündeme getirmen iyi olmuş, package hakkında benimde hiç bilgim yoktu.

Ali'nin anlattıklarından sanki bir isim alanı (namespace) kavramına karşılık geliyor gibi anladım. Acaba package'i bu şekilde düşünebilirmiyiz. Eğer böyle değilse isim alanına karşılık gelen bir D yapısı  var mı?
https://github.com/zafer06 - depo
acehreli (Moderatör) #6
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
zafer:
sanki bir isim alanı (namespace) kavramına karşılık geliyor gibi anladım. Acaba package'i bu şekilde düşünebilirmiyiz.

Aslında değil. 'package' anahtar sözcüğü yalnızca erişim hakları ile ilgili bir konu. 'package' olarak belirtilen olanaklar genele değil, pakede açıktır. (Erişim haklarıyla ilgili derleyici hatalarından söz ediliyordu. Denerken beklenmedik sonuçlar elde edebilirsiniz.

Eğer böyle değilse isim alanına karşılık gelen bir D yapısı  var mı?

Paket tanımlarken işin içine klasör girdiği için doğal olarak paket de isim alanı getiriyor ama tekrar söylemek gerekirse, 'package' anahtar sözcüğü isim alanı tanımlamıyor. Yalnızca erişim haklarını belirliyor.

Modüller isim alanıdır. Ek olarak modüllerin içindeki sınıflar ve yapılar da isim alanıdır: benimModül.BenimSınıf.benimÜye gibi...

Ali
Avatar
Salih Dinçer #7
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #4
acehreli on 2012-05-08, 17:55:
Modülün 'package' olarak işaretlenen olanakları bu pakedin diğer modüllerine de açıktır. Ama bunu deneyebilmek için birden fazla modül dosyası kullanmak gerek.

Örneğin, gösterdiğin kodu saat.d ismiyle kaydet. Aynı klasöre bir de takvim.d diye bir modül yerleştir. Şimdi saat.d ve takvim.d aynı pakede ait olurlar. takvim.d, saat.d içindeki 'package' olanaklarına erişebilir. Ama modül isimlerine pakedin ismini de yazmak gerekiyor.

Bu konular bana çok karışık gelmişti ama sonunda çalışan örnekler bulabilmiştim. Paket kavramı için:

  http://ddili.org/ders/d/moduller.html

Erişim hakları için:

  http://ddili.org/ders/d/sarma.html

Ali
Hocam, şu paket olayını diğer dillerden arınmış bir şekilde anlamaya çalışsam da hala buna vakıf olamadım...:)

Öncelikle D.ershane'deki okul/öğrenci örneğini denedim. Bahsedildiği gibi 3 dosya oluşturdum ve yapıda işaretli olan package'ları kaldırdım. Uygulama yine çalıştı.

Zaten erişimde bir kısıtlama var mı? Özetle yararı ne ki?
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
acehreli (Moderatör) #8
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Salih Dinçer:
yapıda işaretli olan package'ları kaldırdım. Uygulama yine çalıştı.

Varsayılan erişim 'public' olduğu için öyle yapınca herkese açmış oldun. 'package', yabancılara kapalı ama pakede açık olan erişim belirliyor.

Ali
Avatar
Salih Dinçer #9
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Şimdi anlaşıldı, gayet net ama vereceği hata kodunu nakletmek için denemeliydim...

Karşılacağımız hata şu olacakmış:
[atelyeweb@sdb ali]$ dmd okulDefteri.d Okul/ogrenci.d Dershane/defteri.d -w
Dershane/defteri.d(21): Error: struct Okul.ogrenci.Öğrenci member cinsiyet is not accessible
Dershane/defteri.d(21): Error: struct Okul.ogrenci.Öğrenci member cinsiyet is not accessible
Dershane/defteri.d(40): Error: struct Okul.ogrenci.Öğrenci member isim is not accessible
Dershane/defteri.d(40): Error: struct Okul.ogrenci.Öğrenci member isim is not accessible

Bu arada örnekte küçük bir değişiklik yaptım. Dershane ile Okul isminde 2 klasör oluşturdum ve okul.d dosyasını defteri.d şeklinde değiştirdim. Ancak olayı gözlemleyebilmemiz için Okul/defteri.d haricinde bir de Dershane/defteri.d dosyamız var. Sadece modül ismi değişik.

Özetle paket ismi Okul olan kod, Dershane'ye erişebilir ama package şeklinde işaretliler de avcunu yalar...:)

Başarılar...
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
Avatar
Salih Dinçer #10
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Bu konuya biraz daha devam etmeliyiz!

Şimdilik küçük notlar halinde devam edelim; belki sonra makaleleştirebiliriz de...

  • module:

Bunu, bizim kodların bulunduğu paket/klasör ismimiz gibi düşünebiliriz. Her zaman en başta yer almak zorunda ve şu şekilde tanımlanmakta:

"denemelerim.d":
module DENEMELER;
 
void main() {
  //...
}

Eğer bunu ana dosyada kullanmazsanız varsayılan olarak module denemelerim; gibi tanımlanmış oluyor. Yok harici bir dosyada tanımlayacaksanız, dosya ve klasör ismi ile uyumlu olmak zorunda. Ayrıca doğal olarak Türkçe karakter içermemeli. Harici dosyayı çağırırken de konumuzla dolaylı ilişkili olan import'u kullanıyoruz. Bu başlığı en sona bırakalım.

  • public:

Öncelikle, tek dosyadan oluşan her sınıf ve üyesi her zaman public (herkese açık) gibi davranıyor. Yani siz, bu ve ileride göreceğimiz erişim haklarını, tek dosyada kullanırken işler halde olduğunu göremeyebilirsiniz. Çünkü hepsi varsayılan isim alanı içerisinde kardeş kardeş yaşamayı tercih ediyorlar...:)

Belki makalenin tamamını okumamak için çok aceleci olabilirsiniz. Bu durumda D.ershane'deki Sarma Dersi ile devam edin...

D dilinde yazdıklarınız, aksi belirtilmediği müddetçe her zaman public, yani sözcük anlamıyla halka açık. Dolayısıyla kural ihlali olmadığı müddetçe her sınıfın/yapının üyesine erişebilirsiniz. Tabi kısıtlamalara gidilmezse. Bunlar modül seviyesinde ve içinde olmak üzere iki çeşitler:

  • I.package:

Bildiğimiz gibi, import kullanarak derleme anında herhangi bir yerdeki, her hangi bir kodu, ana koda dahil edebiliriz. Ama bunlar ilk maddede kısaca değindiğimiz module'den dolayı ana isim alanı, yani main()'nin içinde bulunduğu bölgedeymiş gibi temsil edilmezler. Öyleyse her modül ayrı bir paket (klasör) içinde varlığını sürdürür. Örnekle açıklarsak, evim ve mahalle isminde 2 paketimiz (directory, dizin) olsun:

"evim/odam.d":
module evim.odam;
 
class ODA {
  package auto koltuğum = "Yaylı";
  auto kapısı = "Açık kahverengi, çelik kapı";
}

Farz edelim mahalleden, Ali'yi ziyaret etmek istiyorlar. Komşuları, bir patikadan geçip Aliler'in (Anadolu'da bazı yörelerde Aligiller de denir) olduğu eve gidecek. Kapıya kadar gelebilirler, çünkü kurucu işlev this()'de salona açılan ODA() tanımlanmış.

"mahalle/yollar.d":
module mahalle.yollar;
import evim.odam;
 
class YOL {
  auto patika = "Ali'nin evine giden en kestirme yol";
  ODA salonAligillerin;
 
  this() {
    salonAligillerin = new ODA();
  }
}
üyedir

Ancak, biz mahalliler olarak ya da main() içindeki bir yönetici, Ali'nin evine erişebilsek de evin reisinin olduğu koltuğa hiç bir zaman oturamayız. Çünkü package ile işaretlenmiş. Yani ev içindekilere açık ama dışarıya değil. Oysa varsayılan olarak halka açık (public) olan kapıya erişebilir ve hakkında bilgi edinebiliriz:
  auto ziyaretYolu = new YOL();
       ziyaretYolu.salonAligillerin.kapısı.writeln//...koltuğum.writeln; ile bitseydi 'not accessible' derleme hatası alırdık... 

  • II.private:

Şimdi de Ali'nin çalışmaOfisi olduğunu ve ondan başkasını giremeyeceği bir oda hayal edelim. Bunu kodlara dökmeye gerek yok çünkü işin içine başka nesneler gireceği için temsil etmesi zor olabilir. Ama bileceğimiz tek bir şey var: Eğer package yerine bu sefer private kullanırsak, aynı modül içinden başka bir sınıf (örn. class KİŞİ), herhangi bir tanımlanmış (new ile hafızada yer ayrılmış) ODA'ya erişse de özel (private)  olarak tanımlanmış hiç bir üyesine erişemeyecektir. Çünkü bu, o sınıf içindekilerin erişebileceği nitelikte işaretlenmiştir. Öyleyse, modüller arasında yaptığımız kısıtlamayı modül içinde de yapabiliriz...

  • II.protected:

  • shared:

  • static:

Düzenleme Notu: Bir daha ki sefer sarma'dan diğer nesne özelliklerine (bir kaçı hemen yukarıda) geçeceğiz. Ama hala sarma konusunu kendi çapımda bitirebilmiş değilim. Çünkü private ile protected arasında henüz bir fark göremiyorum...:)

Ek Not ve Soru: Ayrıca yukarıdaki nitelikleri enum'lar için de denediğimde geçersiz olduklarını gördüm. Bunun nedenini bilmiyorum, oysa enum'lar da bir sınıf içinde üye/nesne gibi davranması gerekiyordu! Şu örnekte neden public gibi davranır?
class Foo {
  // private auto Bar = "isn't public";/*
  private enum Bar = "is public";//*/
}
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
acehreli (Moderatör) #11
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Çok güzel. :) Notlar:

1) 'module' ile verilen isim dosyanın isminden farklı olursa karışıklık olabiliyor.

2) 'private'ı ya karıştırmışsın ya da yanlış anaşılabiliyor. D'nin 'private'ı örneğin C++'ınki gibi değil. 'private', "sınıfa özel" demek değil. Modüle özel demek. Bir sınıfın içindeki 'private' üyeye o sınıfın modülündeki her kod erişebilir. Bunu, sınıfı yazan modülü de yazmıştır mantığı ile böyle tasarlamışlar. Kişinin kendisini kendisinden korumaya gerek yok gibi düşünmüşler. C++ gibi başka dillerden gelenlerin bazıları D'nin bu seçimini yadırgarlar.

3) Ek olarak, bu gibi isimlerde takı kullanmamak daha kullanışlı değil mi? Örneğin, ev kavramını temsil eden bir modülün ismi 'ev', dosyasının ismi de 'ev.d' olmalı. 'evim.d' gibi olunca yalnızca benim evimi temsil etmiş gibi anlaşılmaz mı? Yoksa, içinde evler bulunan bir köy olduğunda üyesini 'Evim[] evler;' diye tanımlamak gerekir ve sanki içinde benim evimden bir çok kopya varmış gibi görünür. Öte yandan, eğer 'evim.d'nin içindeki türün ismi zaten 'Ev' ise neden dosyasının ismi 'evim.d' olsun diye de düşünülebilir.

private ile protected arasında henüz bir fark göremiyorum.

private: Bu üyeye yalnızca bu modül erişebilir

protected: Bu üyeye bu paketteki başka modüller de erişebilir

Şu örnekte neden public gibi davranır?

O örneği tam anlamadım ama belki yukarıda yazdıklarımla ilgilidir. (?)

Ali
Avatar
Salih Dinçer #12
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
acehreli:
'module' ile verilen isim dosyanın isminden farklı olursa karışıklık olabiliyor.
Hocam sanırım main.d'den bahsediyorsun? Çünkü alt modüllerde farklı dosya ismi olunca "conflicts" hatası alıyoruz.

acehreli:
'private'ı ya karıştırmışsın ya da yanlış anaşılabiliyor. D'nin 'private'ı örneğin C++'ınki gibi değil. 'private', "sınıfa özel" demek değil. Modüle özel demek
Sanırım karıştırıyor olabilirim, ben bu ikisi üzerinde biraz daha deneme yapayım...:)

acehreli:
Ek olarak, bu gibi isimlerde takı kullanmamak daha kullanışlı değil mi?
Bu takıları bilinçli olarak, insancıl olsun diye yaptım. Ancak geniş bir projede bu alışkanlık iyi değil.

acehreli:
O örneği tam anlamadım ama belki yukarıda yazdıklarımla ilgilidir. (?)
Belki ilgili olabilir ama birebir örneği denediğimizde sanki private yazılmamış gibi kod derleniyor. Sanırım enum'ların gerçekte bir değişken değil makro gibi çalışmalarından olsa gerek. Yani bir enum derlenirken nerelerde geçiyorsa oralara birebir karşılığı yerleştiriliyor.
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
acehreli (Moderatör) #13
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Salih Dinçer:
Hocam sanırım main.d'den bahsediyorsun? Çünkü alt modüllerde farklı dosya ismi olunca "conflicts" hatası alıyoruz.

O yüzden denemelerim.d modülüne DENEMELER dememek gerek. Ama haklısın: kimse main'in bulunduğu modülü import etmez. :)

Sanırım enum'ların gerçekte bir değişken değil makro gibi çalışmalarından olsa gerek. Yani bir enum derlenirken nerelerde geçiyorsa oralara birebir karşılığı yerleştiriliyor.

Anladım. Evet, private'a uymalı gibi geliyor... Öte yandan, öyle enum hazır değerler değiştirilemediklerine göre 'private' olmaları da diğer değişkenler kadar önemli değil. Bence yine de uymalı.

Tarih öncesinden (2005) aşağıdaki gibi bir tartışma buldum. Anlaşılan, senin de tahmin ettiğin gibi bu bir hata değilmiş çünkü erişim belirteçleri bildirimleri (declaration'ları) etkiliyormuş. Oysa enum'lar tanımmış (definition).

  http://forum.dlang.org/thread/cue3ro$d5i$1@digitaldaemon.com

Ali
Avatar
Salih Dinçer #14
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Denemelerimi sürdürüyorum...

Yaşam süreçleri konusunda aşağıdaki gibi bir deneme yaptım. Ne olup bittiğini anlamak için, mutfak tarafına geçip assembly kodlarına da baktım. Çok uzatmayacağım çünkü ummadığım bir sonuç çıktı, tüm hayallerim yıkıldı...:)

Evet, hemen altındaki gibi bir sonuç elde edemiyorsunuz; anlaşılan, seçeneklerin her biri güzel parantezler gibi ayrı bir kapsam...
//import core.stdc.stdio;/*
import std.stdio;//*/
 
  class A {
    override
    string toString() const {
      return "A SINIFI";
    }
  }
 
  class B {
    override
    string toString() const {
      return "B SINIFI";
    }
  }
 
void main(string[] arg) {
  A bir;
  B iki;
  
  char seçenekler = arg.length > 1 ? arg[1][0] : 0;
 
  switch(seçenekler) {
    case 0:
      printf("PARAMETRE KULLANILMALI\n"); break;
    case 1:
      bir = new A(); goto default;
    case 3:
      bir = new A();
    case 2:
      iki = new B();
    default:
      if(bir) bir.writeln;
      if(iki) iki.writeln;
  }
} /* BEKLENEN:
 
./önSeçimliSınıflar
PARAMETRE KULLANILMALI
 
./önSeçimliSınıflar 1
A SINIFI
 
./önSeçimliSınıflar 2
B SINIFI
 
./önSeçimliSınıflar 3
A SINIFI
B SINIFI
*/
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
Avatar
Salih Dinçer #15
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Çok ilginç!

Sınıflar, switch case ifadesi için hiç kurulamıyor. Aslında kuruluyor olmalı, çünkü assembly kodlarında kurucu alt yordama dallanıyor ama aşağıdaki gibi düzenleme yaptığımda kurulmadığı sonucunu çıkarıyorum!
  class A {
    this() { "A SINIFI".writeln; }
  }
 
  class B {
    this() { "B SINIFI".writeln; }
  }
Sanki derleyici, hangi parametrenin geleceğini tahmin edemediği için bellekte onun için bir yer ayırmıyor ya da kurucu üye olan this()'i çalıştırmıyor olmalı çünkü ekrana bir şey yazmamayı tercih ediyor...:)
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
Doğrulama Kodu: VeriCode Lütfen resimde gördüğünüz doğrulama kodunu girin:
İfadeler: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Özel Karakterler:
Sayfa:  1  2  sonraki 
Forum: Ders Arası RSS
Bağlı değilsiniz. · Şifremi unuttum · ÜYELİK
This board is powered by the Unclassified NewsBoard software, 20100516-dev, © 2003-10 by Yves Goergen
Şu an: 2017-11-18, 04:01:35 (UTC -08:00)