Bu çok teknik bir konu aslında. Bu iki şekilde olabilir. 1. si nesneye yönelik programlama tekniği kullanarak 2. si ise Arabirimleri (Interface) kullanarak. 2. teknik Delphi 7 ve sonrasında desteklenen bir teknik olduğu için daha önceki delphi versiyonlarında çalışmaz.
----------------
1. Nesne Programlama Kullanarak:
Önce basit temel bir nesne hazırlayalım:
Kod: Tümünü seç
type
THesapla=class;
public
function Hesapla:Real;virtual;abstract;
end;
bu nesne için
function THesapla.Hesapla:Real; fonksiyonu tanımlanmaz "abstract" anahtar sözcüğü bunun bu nesnede değil de bundan türeyen nesnelerde tanımlanacağını belirtir. "virtual" anahtar sözcüğü ise "Hesapla" metodunun bundan türeyen nesnelerde değiştirilebileceğini belirtir. Şimdi FIFO, LIFO ve ORTALAMA ya göre hesaplama yapan 3 nesne türetelim.
Kod: Tümünü seç
TFIFO=class(THesapla);
public
function Hesapla:Real;override;
end;
TLIFO=class(THesapla);
public
function Hesapla:Real;override;
end;
TORT=class(THesapla);
public
function Hesapla:Real;override;
end;
.
.
function TFIFO.Hesapla:Real;
begin
.
.
Result:=??;
end;
function TLIFO.Hesapla:Real;
begin
.
.
Result:=??;
end;
function TORT.Hesapla:Real;
begin
.
.
Result:=??;
end;
artık elimizde değişik yöntemlere göre hesap yapabilen 3 tane nesne bulunuyor. Burada "override" anahtar sözcüğü ise önceden "virtual" ya da "dynamic" olarak tanımlanan fonksiyon yada prosedürleri veya "constructor" metotları çocuk nesne de daha değişik şekilde çalışmasını sağlamaya yarar. Eğer ata nesne içinde bulunan kodlarıda kullanmak istersek (mesela TComponent'ten türemeler de Create kodlarının çalışması gerekir) "inherited Hesapla;" dememiz gerecekti ama ben "abstract" olarak tanımladığım için bu satır çalışma anında hata çıkarır. Çünkü THesapla nesnesinde Hesapla isimli fonksiyonun kodu bulunmamaktadır. Basit bir örnek yazarsak:
Kod: Tümünü seç
var Hesap:THesapla;
begin
try
if FIFO.Checked then Hesap:=TFIFO.Create
else if LIFO.Checked then Hesap:=TLIFO.Create
else Hesap:=TORT.Create;
ShowMessage(FloatToStr(Hesap.Hesapla));{burada yapılan seçim neyse ona göre hesaplama yapacaktır.}
finally
Hesap.Free;
end;
end;
görüldüğü küçük nesneler yazarak ve hesaplamaları bunlara dağıtarak bir yığın koddan kurtulduk. Bunu basit bir örnek olsun diye yazdım. Senin form üzerinde uygulayacağın teknik olarak çözüm üretirsek aşağıda ki gibi bir kod yaz ve myForm.pas olarak kaydet.
Kod: Tümünü seç
unit myForm;
interface
uses Forms;
type
TForm=class(Forms.TForm)
public
procedure OrtakMetot1;virtual;abstract;
function OrtakMetot2:Boolean;virtual;
function OrtakMetot3:Boolean;virtual;abstract;
end;
implementation
function TForm.OrtakMetot2: Boolean;{abstract; kullanılmadığı zaman kodu yazılarak tanımlanır}
begin
end;
Caption:='Çalıştırıldım';
//Result:=True;
end.
projendeki tüm paslarda üstte uses satırında en sona (Forms'tan sonraki bir yere) myForm ünitesini ekle. Artık tüm formlarında OrtakMetot1 prosedürü ve OrtakMetot2 fonksiyonu olacaktır (Form1.OrtakMetot2 vs.). Şimdi bir formda bunun çalışmasını yazmak veya değiştirmek istersen şu şekilde o forma yazmalısın.
Kod: Tümünü seç
type
TForm1=class(TForm)
.
.
public
procedure OrtakMetot1;override;
function OrtakMetot2:Boolean;override;
function OrtakMetot3:Boolean;override;
end;
implementation
procedure TForm1.OrtakMetot1;
begin
....
end;
function TForm1.OrtakMetot2: Boolean;
begin
...
{"inherited;" veya "inherited OrtakMetot2;" yazılırsa TForm nesnesinde yazılan OrtakMetot2 fonksiyonu da çalışacaktır.}
end;
function TForm1.OrtakMetot3: Boolean;
begin
...
end;
end.
bu tanımlamadan sonra, tanımlaması yapılan tüm formlarda OrtakMetot1,OrtakMetot2 ve OrtakMetot3 metotlarını THesapla örneğinde olduğu gibi çalıştırılabilir.
----------------
Bu çok karışık geldiyse o zaman 2. yönteme göz at. Bu yöntemi Delphi 7 ve sonrası desteklemektedir.
----------------
2.Arabirimleri (Interface) Kullanarak:
Burada nesnelerin yapısında hiç bir değişiklik yapmana gerek yoktur. Sadece yapısı class'tan biraz farklı olan interface tanımlaman gerekecek ve bu arayüzde ortak olması gereken prosedür ve fonksiyonların sadece tanımlamalarını yazman gerekecek. (begin-end; bloğu içinde kodlar gerekmez çünkü interface sadece özet bilgi amaçlıdır)
Kod: Tümünü seç
unit Genel;
interface
uses SysUtils, Forms;
type
IFormGenel=interface(IUnknown)
['{24497238-ADE0-4381-953E-808699155BB3}']
procedure OrtakMetot1;
function OrtakMetot2:Boolean;
function OrtakMetot3:Boolean;
end;
implementation
end.
yukarıda farklı olarak
['{24497238-ADE0-4381-953E-808699155BB3}'] yazan satır bulunmaktadır. Bu değeri elde etmek için
Ctrl+Shift+G tuşlarına basman gerekecek. Değerin işlevi bu arayüze dünyada bulunan diğer arayüzlerden farklı bir sayısal değer vermek ama bizim için bunun önemi yok. Yukarıda Genel.pas isimli dosya oluşturulduktan sonra bu ortak metotları tanımlayacak tüm formaları şu şekilde yapılandırmalısın. Uses satırında Genel'i eklememiz gerekecek.
Kod: Tümünü seç
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Genel;
type
TForm1 = class(TForm, IFormGenel)
.
.
private
{ Private declarations }
public
{ Public declarations }
procedure OrtakMetot1;
function OrtakMetot2:Boolean;
function OrtakMetot3:Boolean;
{eğer IFormGenel arabirimi kullanılarak nesne türetilirse IFormGenel içinde bulunan tüm metotlar aynı IFormGenel'de tanımlı olduğu şekilde bu nesnede tanımlanmalıdır.(OrtakMetot1,OrtakMetot2,OrtakMetot3)}
end;
implementation
procedure TForm1.OrtakMetot1;
begin
....
end;
function TForm1.OrtakMetot2: Boolean;
begin
...
end;
function TForm1.OrtakMetot3: Boolean;
begin
...
end;
end.
şimdi tanımlamalar yapıldıktan sonra ortak bir noktadan bu nesnedeki bu metotları kullanmak istediğimizde şu kodları yazmamız gerekecek.
Kod: Tümünü seç
//uses ta SysUtils kullanılıyor;
function MetotlariCalistir(const Form:TObject):Boolean;
var i:Integer; GenelForm:IFormGenel;
begin
Result:=True;
if Assigned(Form) then try
if Supports(Form,IFormGenel,GenelForm) then begin
GenelForm.OrtakMetot1;
GenelForm.OrtakMetot2;
GenelForm.OrtakMetot3;
end;
except
Result:=False;
end;
end;
ben burada
MetotlariCalistir(Form1) dediğim zaman TForm1 içindeki OrtakMetot1,OrtakMetot2 ve OrtakMetot3 çalışacaktır. Hatta:
Kod: Tümünü seç
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Genel;
type
TDenemeNesnesi = class(TComponent, IFormGenel)
private
{ Private declarations }
public
{ Public declarations }
procedure OrtakMetot1;
function OrtakMetot2:Boolean;
function OrtakMetot3:Boolean;
{eğer IFormGenel arabirimi kullanılarak nesne türetilirse IFormGenel içinde bulunan tüm metotlar aynı IFormGenel'de tanımlı olduğu şekilde bu nesnede tanımlanmalıdır.(OrtakMetot1,OrtakMetot2,OrtakMetot3)}
end;
implementation
procedure TDenemeNesnesi.OrtakMetot1;
begin
....
end;
function TDenemeNesnesi.OrtakMetot2: Boolean;
begin
...
end;
function TDenemeNesnesi.OrtakMetot3: Boolean;
begin
...
end;
end.
şeklinde form olmayan bir nesneyi IFormGenel arabirimiyle tanımlarsak ve
MetotlariCalistir(DenemeNesnesi1) yazarsak bu sefer TDenemeNesnesi'ne ait ortak metotlar çalışacaktır.
-----------------
Bu konular aslında derin ve zaman isteyen konulardır. Ben bunları Charlie Calvert (Delphi4) ve Marco Cantu(Delphi7) kitaplarından okudum. Aslında zamanını bu konuları öğrenmek için muhakkak ayır. Özellikle nesne programlama tekniğini. Eğer zamanını alacağını düşünüyorsan gelecekte yapacağın işlerde kaybettiğinden çok daha fazlasını kazanacağını garanti ederim. Ayrıca akla ilk gelen soru nesneleri nasıl tasarlamak gerektiğidir. Bu teknik bir bilgi değildir bu tamamen tecrübedir. Bu konularla ne kadar haşır neşir olur örnekler yaparsan o kadar sağlıklı nesneler üretmeyi başarabilirsin.
????????
Bir şeyi belirtmeyi unutmuşum. Senin bunu MetotlariCalistir(TForm(ortak.tag)) yazarak kullanman gerekecek