Statik ve dinamik metodlarin garip dunyasi

// 26 Nisan 2011 // Delphi

Uzun zamandir Delphi ile ilgili bir makale , yazi vs. yazmadim. Birkac kere elim gider gibi oldu ama nedense sonunu getiremedim. Delphi ile ilgili yazilar yazdigim blogu kapattim , kisisel blogumda oylesine duruyor cok ellemiyorum. Biryerlerde insanin login olabilecegi baska wordpressler olmasi guzel sey :)

Evet yine belki bir makale yazmadim ama guldururken dusunduren 10 tane soru hazirladim. Sorular statik ve dinamik metodlarin calisma mantiklarini birebir gormenizi saglayan cinsten sorular. Gercekten sorulari teker teker programa koyup calistirip ciktilarina baktiginizda insana cok seyler ogretebiliyor. Hatta sorulardan bir tanesini Access Violatin verecegini dusunurek hazirlamistim , calisitirinca Access violation hatasi vermeyince bir kac saniyeligine sok olmustum :)

Once sorulari bir calistiralim , ciktilara bakalim , sonrasin da ise ciktilarin nasil olupta boyle sonuclar urettigi ile ilgili hep beraber burda kafa patlatalim :)

program statikAlistirma;

{$APPTYPE CONSOLE}

uses
  SysUtils;

type
TDosya = Class
  private
    FFileName: String;
    procedure SetFileName(const Value: String);
  protected
  public
  procedure IslemYap();virtual;
  procedure statikMethod();
  property FileName:String read FFileName write SetFileName;
End;

TXMLDosya = Class(TDosya)
  private
  protected
  public
  procedure IslemYap();override;
End;

TCSVDosya = Class(TDosya)
  private
  protected
  public
  procedure statikMethod();
  procedure IslemYap();
End;


{ TDosya }

procedure TDosya.IslemYap;
begin
  Writeln(FileName + ' islem yapiliyor');
end;

procedure TDosya.SetFileName(const Value: String);
begin
  FFileName := Value;
end;

procedure TDosya.statikMethod;
begin
Writeln('TDosya sinifinin statik methodu');
end;

{ TXMLDosya }

procedure TXMLDosya.IslemYap;
begin
  inherited;
  Writeln('XML dosya isleniyor');
end;

{ TCSVDosya }

procedure TCSVDosya.IslemYap;
begin
  Writeln('CSV dosya isleniyor');
end;

procedure TCSVDosya.statikMethod;
begin
  Writeln('CSV dosyasinin statik methodu');
end;


var
dosya:TDosya;
begin
  try
    dosya :=TDosya.Create;
    dosya.FileName :='deneme';
    TCSVDosya(dosya).statikMethod;
    FreeAndNil(dosya);
    readln;
    { TODO -oUser -cConsole Main : Insert code here }
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

soru-1 asagidaki sekilde programi calistirirsan ekranda ne yazar ? Nicin?

var
dosya:TDosya;
begin
  try
    dosya :=TDosya.Create;
    dosya.statikMethod;
    FreeAndNil(dosya);
    readln;

soru-2 asagidaki sekilde programi calistirirsan ekranda ne yazar ? Nicin?

var
dosya:TDosya;
begin
  try
    dosya :=TCSVDosya.Create;
    dosya.statikMethod;
    FreeAndNil(dosya);
    readln;

soru-3 asagidaki sekilde programi calistirirsan ekranda ne yazar ? Nicin?

var
dosya:TCSVDosya;
begin
  try
    dosya :=TCSVDosya.Create;
    dosya.statikMethod;
    FreeAndNil(dosya);
    readln;

soru-3 asagidaki sekilde programi calistirirsan ekranda ne yazar ? Nicin?

var
dosya:TCSVDosya;
begin
  try
    dosya :=TCSVDosya.Create;
    TDosya(dosya).statikMethod;
    FreeAndNil(dosya);
    readln;

soru-4 asagidaki sekilde programi calistirirsan ekranda ne yazar ? Nicin?

var
dosya:TDosya;
begin
  try
    dosya :=TCSVDosya.Create;
    TCSVDosya(dosya).statikMethod;
    FreeAndNil(dosya);
    readln;

soru-5 asagidaki sekilde programi calistirirsan ekranda ne yazar ? Nicin?

var
dosya:TXMLDosya;
begin
  try
    dosya :=TXMLDosya.Create;
    dosya.statikMethod;
    FreeAndNil(dosya);
    readln;

soru-6 asagidaki sekilde programi calistirirsan ekranda ne yazar ? Nicin?

var
dosya:TDosya;
begin
  try
    dosya :=TXMLDosya.Create;
    dosya.FileName :='deneme';
    dosya.IslemYap;
    FreeAndNil(dosya);
    readln;

soru-7 asagidaki sekilde programi calistirirsan ekranda ne yazar ? Nicin?

var
dosya:TDosya;
begin
  try
    dosya :=TCSVDosya.Create;
    dosya.FileName :='deneme';
    dosya.IslemYap;
    FreeAndNil(dosya);
    readln;

soru-8 asagidaki sekilde programi calistirirsan ekranda ne yazar ? Nicin?

var
dosya:TDosya;
begin
  try
    dosya :=TXMLDosya.Create;
    dosya.FileName :='deneme';
    TDosya(dosya).IslemYap;
    FreeAndNil(dosya);
    readln;

soru-9 asagidaki sekilde programi calistirirsan ekranda ne yazar ? Nicin?

var
dosya:TDosya;
begin
  try
    dosya :=TDosya.Create;
    dosya.FileName :='deneme';
    TXMLDosya(dosya).IslemYap;
    FreeAndNil(dosya);
    readln;

soru-10 asagidaki sekilde programi calistirirsan ekranda ne yazar ? Nicin?

var
dosya:TDosya;
begin
  try
    dosya :=TDosya.Create;
    dosya.FileName :='deneme';
    TCSVDosya(dosya).statikMethod;
    FreeAndNil(dosya);
    readln;

“Statik ve dinamik metodlarin garip dunyasi” için 7 Yorum

  1. Tuğrul HELVACI diyor ki:

    Ellerine sağlık sadettinim. Gayet eğitici ve öğretici bir yazı olmuş. Benim de çok uzun zamandır yazmayı planladığım ama elimin gitmediği pek çok makale var. Bu sorularına bizler en son yanıt verelim. Bakalım bir kaç kişiden başka takip eden varmıymış blogu :)

    Hazır burada iken geçenlerde yaptığım ve bulmakta epey zorlandığım bir hatamı da yazayım, belki birilerinin aynı hataya rast gelmesine de mani olmuş oluruz. Genellikle programlarımda memory leak’lere çok dikkat ederek kod yazarım ama benim de başıma memory leak belası gelmez değilmiş demek ki :) Siz siz olun her daim projenin kaynak kodunda ReportMemoryLeaksOnShutDown seçeneğini açıkta tutun ki böcekleri büyüyüp serpilmeden halledebilesiniz ;)

    Gelelim küçük örneğimize;

    Genellikle bir form oluşturacağım zaman o formun daha önce oluşturulup oluşturulmadığını kontrol etmem. Bunu derleyiciye bırakırım. Kullandığım yöntemi ve hatamı göreceksinizdir muhtemelen.

    TForm2 = class(TForm)
    private
    fAdiSoyadi : String;
    public
    property AdiSoyadi : String read fAdiSoyadi write fAdiSoyadi;
    end;
    // Bu formun OnClose’unda Action := caFree ve form2 := nil; olduğunu hayal edin.

    uses
    unit2;


    procedure TForm1.Button1Click(Sender : TObject);
    begin
    try
    form2.AdiSoyadi := ‘Deneme’;
    form2.Show;
    except
    form2 := TForm2.Create(Application);
    form2.AdiSoyadi := ‘Deneme’;
    form2.Show;
    end;
    end;

    Yukarıdaki metodolojide; form yok ise hata verecek dolayısı ile except bloğuna sıçrayacak ve hatayı raise ile yeniden tetiklemediğim için formumu düzgün bir şekilde oluşturabilecek ve gösterebileceğim. Ancak; form2.AdiSoyadi atamasını yanlışlıkla try bloğu içinde yaptığım için ve o da nil olan bir nesnenin AdiSoyadi alanına bir şey yazmaya çalıştığı için doğal olarak Access Violation hatası ile karşılaşacağım. Ama burada ilginç olan, programın çıkışında aynı zamanda bir UnicodeString kadarlık memory leak’e de neden olmam. Anlaşılan o ki; hafızada rezervasyon yapılmamış yani nil olan bir nesne referansını kullanarak AdiSoyadi alanına bir şey yazıyor olmaya çalışmam, rastgele bir hafıza bölgesine cidden birşeyler yazıldığının göstergesi. Çünkü stringler referans sayımlıdır ve bu atamadan sonra atanan hafıza bölgesine referansı azaltabilecek herhangi bir referans yok.

    Biraz uzatmış olabilirim ama umarım ne demek istediğimi anlatabilmişimdir.

  2. sadettinpolat diyor ki:

    Object pascal ya da OOP konusunda ince noktalari ogrenmek isteyenler icin acele etmeyelim , ciktilar uzerine yorumlarimizi biraz erteleyelim :)

    OOP ya da Object Pascal ile ilgili bir sertifika icin soru hazirlamam gerekse bu konudan en az 3 soru koyardim sinava :)

    Memory leak olayina gelince ise

    1-Bu sekilde bir durumda memory leak olusabilecegi hakkinda jetonum benim de mesajini okuduktan sonra dustu. Dikkat edilmesi gereken bir durum.
    2-Benim gibi unutkan arkadaslar ReportMemoryLeaksOnShutdown:=DebugHook<>0; seklinde bir kullanim tercih ederlerse musterilerden “yahu program kapanirken hata veriyor” tarzi geri donusler almayacaklaridir :)

  3. Hasan MANZAK diyor ki:

    8 ve 9 hariç tüm sonuçlar beklediğim gibi çıktı. Sınıfların statik metodları, casting işlemleri, overriding, inheritance… Fakat 8. ve 9. sorularda sonuçların ters çıkma sebebini kavrayamadım henüz :)

    TDosya tipinde tanımladım, TXMLDosya olarak create ettim, TDosya’ya cast edip IslemYap çağırdım… Nasıl oldu da TXMLDosya.IslemYap koşuldu?

    Aynı şekilde TDosya olarak create edip TXMLDosya’ya cast ettim; nasıl oldu da TDosya.IslemYap koşuldu?.. Tamam, bunu biraz sallayarak açıklayabilirim ( create ettiğin tip vs vs gibi ), ama 8. soruda özellikle TDosya casting işleminden sonra nasıl miras alan sınıfın metodu koşuldu anlayamadım bir türlü ((:

  4. Veli BOZATLI diyor ki:

    Emeğinize sağlık Sadettin Bey.
    Daha önce okumuştum ama kodları ancak test etme fırsatım oldu.
    Sonlara doğru biraz şaşırmadım değil :)

  5. Selman Erol diyor ki:

    Bu kodu bende gpslerin sunucunda deneyeceğim bende kurtulamadığım bir kapatma hatası alıyorum. Belki işe yarar.

  6. Sedat Nazik diyor ki:

    Soru 11:

    var dosya: TDosya;
    begin
    try
    dosya := TXMLDosya.Create;
    dosya.FileName := ‘deneme’;
    TCSVDosya(dosya).IslemYap;
    FreeAndNil(dosya);
    readln;

    Soru:12

    var dosya: TDosya;
    begin
    try
    dosya := TCSVDosya.Create;
    dosya.FileName := ‘deneme’;
    TXMLDosya(dosya).IslemYap;
    FreeAndNil(dosya);
    readln;

    :D

Yorum Yazın