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