Nedense interfaceleri aklımda hep com ile ilişkilendirdiğim ve com'dan da çok fazla hoşlanmadığım için hep uzak durdum. Karşıma çıktığında ise hep şöyle gözucuyla bakarak ortamdan sıvışma yolunu seçtim. Genelde java örnekleri bulunan bir kitapta sıklıkla interfacelerden söz edilmesi, bazı tasarım kalıplarını uygularken interfaclerin kullanılması, bazı tekniklerin uygulanması sırasında interfaclerin ne kadar işe yaradığından bahsedilmesi ve son olarakta furkan'la yaptığımız sohbette konunun interfacelere gelmesi ortamdan sıvışmakla pekte iyi yapmadığım hususunda beni uyardı.
Elimdeki kitapların ilgili bölümlerini tekrar gözden geçirerek -bu sefer gözucuyla değil- nedir ne değildir anlamaya çalıştım. İlk anladığım nokta com ile interfacein göbeklerinin bir kesilmediği oldu. Kylix'te bile interfaceler mevcutmuş hatta benim gibi com ile gelen bir teknoloji olduğunu düşünen bir çok kişi olmalı ki daha önceden IUnknown olarak delphide bulunan interface kavramını delphi 5 ten sonra borland -kendi interface desteğini tam olarak gösterebilmek için- com'un ata nesnesi olan IUnknown tanımından IInterface tanımına geçmeyi uygun görmüş. Yani interfaceler oop'un çok önemli bir öğesi olmakla birlikte güçlü ve popüler dillerin hepsi bu kavramı destekler pozisyonda. Valla ms, com sayesinde bu interfaceleri öyle bir hale sokmuşki bu kavramın ms'nin olmadığını çakozlamak biraz zaman alıyor :) gerçi ms bunu hep yapıyor. xml'i ms standartı olarak bilen kaç kişi vardır sizce?
Ya neyse boşverin biz konumuza dönelim. -Asım, şu pencereyi kapa ceyran yapıyor.-
Interfaceler kısaca nasıl tarif edilir bilmiyorum ama okuduklarıma dayanarak şunu sallayabilirim. Interfaceler sadece "NE" sorusuna yanıt verirler, "NASIL" sorusuna ise yanıt vermezler.
Bu da nedemek şimdi ?
İlkokuldaki türkçe dersimize dönelim. "Yazılışları(okunuşlaru) aynı anlamları farklı" olan kelimelere ne diyorduk ? eşsesli veya sesteş. interfacelerde bunun gibi birşey işte. Dışardan bakınca bütün metod ve fonksiyonları aynı ama içerden bakınca farklı. dışı seni yakar içi beni misali.... hepten karıştı ya .... !
-Her yiğidin yoğurt yiyişi farklı mıdır abicim?
-farklıdır
-peki ben fazla kafa karıştırmadan Yigit.YogurtYe diye bir komut versem ve bu komutun -değişik yiğitler için değişik sonuçlar vermesini sağlayabilir miyim ?
-bildim bildim. interface kullanacan di mi?
-sen ne zekisiyin ya. gözlerim yaşardı.
hah. kitaptaki örnek geldi aklıma. bu sefer kesin anlarsınız. bu yoğurt meselesine dönecez sonra.
arabirimlerler dolaptaki kıyafetler gibidir. o gün hangi kıyafeti (Tobject) giymek isterseniz (siz /gizli özne (Interface)) onu giyebilirsiniz. takım elbise, spor, plaj , palyaço, pijama..... ne varsa artık...
şu yoğurt meselesine geri dönelim.
şimdi interface i yazıyorum. -bismillah-
type IYigit = Interface(IInterface) Procedure YogurtYe(); end;ne baktın ? farklı mı geldi? :) Bu kadar ya. 2 satır. Dedik ya "ne" sorusuna cevap verir "nasıl" sorusuna cevap vermez diye. işte "ne" sorusuna cevap veriyor. Yiğit ne yiyecek? el cevap. Yoğurt yiyecek. yiyecek yüklem... kim ? yiğit, özne. yiğit ne yiyecek ? yoğurt,belirtili nesne oss suali gibi oldu. şimdi bu interface'i kullanan bir sınıfta burda belirtilen YogurtYe prosedürünü kendine göre yorumlayıp kullanacak. Bu kısımda "nasıl" sorusunun cevabı oluyor. şimdi düşünelim. bu interfacei kullanan bir den fazla sınıfımız varsa ne olur? cevabı basit. "ne" sorusuna karşılık birden fazla (nesne sayımız kadar) "nasıl" cevabımız olur. örnek mi?
TFatihSultanMehmet = Class(TInterfacedObject,IYigit) public Procedure YogurtYe(); end; TKanuniSultanSuleyman = Class(TInterfacedObject,IYigit) public Procedure YogurtYe(); end;Yukarıdaki kodlarda iki tane yiğidimiz var ve bu yiğitlerimizin ikisi de IYigit arabirimini kullanıyorlar. Yani iki nesnede de YogurtYe prosedurumuz var ama bunların gövdeleri kendilerine özel.
procedure TFatihSultanMehmet.YogurtYe; begin Showmessage('Önce Kaymağını Ye') end; { TKanuniSultanSuleyman } constructor TKanuniSultanSuleyman.Create(Stil: String); begin Showmessage('Bandıra Bandıra Ye') end;Yahu iyi de ne işimize yaradı bu şimdi derseniz mesela şöyle bir kod yazabilirsiniz. yukarıdaki "istediğiniz kıyafeti giyebilirsiniz" örneğini hatırlayın.
procedure TForm1.Button1Click(Sender: TObject); var Yigit :IYigit; begin if RadioButton1.Checked Then Yigit := TFatihSultanMehmet.Create() else Yigit := TKanuniSultanSuleyman.Create(); Yigit.YogurtYe; end;eğer Yigit := TFatihSultanMehmet.Create() satırı çalışmışsa ekranda "Önce Kaymağını Ye" mesajını görürüz aksi takdirde "Bandıra Bandıra Ye" mesajını görürüz. Bunu sağlayan satıra dikkat edin. Yigit.YogurtYe; daha bir çok özelliği mevcut ama şimdilik bu kadar yeter diycem ama bir kaçını söylemeden edemiycem. - bir sınıf birden fazla interface kullanabilir. TKanuniSultanSuleyman = Class(TInterfacedObject,IYigit,IYigit2,....,xxxx) gibi -Birden fazla interface kullanıldığında aynı isimler varsa bunlara lakap verilebilir -Her interface'e GUID numaraları verilmesinde fayda var. .net için gerekli olmasada win32 için gerek olabilir. -as, is operatorlerini kullanabilirsiniz. -google :) bu da hazır yapılmış bir örnek constructor Create(Stil:String); satırı biraz gereksiz oldu gibi ama bu satır olmadan ctrl + space'i bi türlü çalıştıramadım.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
IYigit = Interface(IInterface)
Procedure YogurtYe();
end;
TYigitlerinAtasi = class(TInterfacedObject)
private
fStil:String;
end;
TFatihSultanMehmet = Class(TYigitlerinAtasi,IYigit)
public
Procedure YogurtYe();
constructor Create(Stil:String); //bunlar olmadan kod tamamlama bir türlü aktif olmadı nedense
end;
TKanuniSultanSuleyman = Class(TYigitlerinAtasi,IYigit)
public
Procedure YogurtYe();
constructor Create(Stil:String); //bunlar olmadan kod tamamlama bir türlü aktif olmadı nedense
end;
TForm1 = class(TForm)
Button1: TButton;
RadioButton1: TRadioButton;
RadioButton2: TRadioButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
Yigit :IYigit;
begin
if RadioButton1.Checked Then
Yigit := TFatihSultanMehmet.Create('Önce Kaymağını Ye')
else
Yigit := TKanuniSultanSuleyman.Create('Bandıra Bandıra Ye');
Yigit.YogurtYe;
end;
{ TFatihSultanMehmet }
constructor TFatihSultanMehmet.Create(Stil: String);
begin
fStil := Stil;
end;
procedure TFatihSultanMehmet.YogurtYe;
begin
ShowMessage(fStil);
end;
{ TKanuniSultanSuleyman }
constructor TKanuniSultanSuleyman.Create(Stil: String);
begin
fStil := Stil;
end;
procedure TKanuniSultanSuleyman.YogurtYe;
begin
ShowMessage(fStil);
end;
end.
bu da dfm dosyası
object Form1: TForm1
Left = 216
Top = 140
Width = 696
Height = 480
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object Button1: TButton
Left = 48
Top = 176
Width = 217
Height = 25
Caption = 'afiyet olsun'
TabOrder = 0
OnClick = Button1Click
end
object RadioButton1: TRadioButton
Left = 40
Top = 120
Width = 225
Height = 17
Caption = 'fatih sultan mehmet yiyişi'
Checked = True
TabOrder = 1
TabStop = True
end
object RadioButton2: TRadioButton
Left = 40
Top = 144
Width = 209
Height = 17
Caption = 'kanuni sultan süleyman yiyişi'
TabOrder = 2
end
end
Yorumlar