Showing posts with label c#. Show all posts
Showing posts with label c#. Show all posts

Saturday, March 9, 2013

Setup Oluşturma (c#)

1. adım:  Solution explorer kısmındaki solution dosyamıza sağ tıklıyoruz.














2. adım:  Add new project  diyoruz.

3. adım:  Other other project types'i seçiyoruz.

4. adım:  Setup and deployment proje tipini seçiyoruz.

5. adım: Visual studio installer'i seçiyoruz.

6. adım: Açılan pencereden setup project'i seçip oluşturuyoruz.



7. adım:  Solution explorer kısmında oluşturduğumuz setup dosyamıza sağ tıklayıp build ediyoruz.














Setup dosyamız projemizin bulunduğu dizindeki debug klasöründe oluşturuldu.

Thursday, March 7, 2013

Video Player Programı (C#)


Program.Cs  :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace WindowsFormsApplication2
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new frmMain());
        }
    }
}


MainForm.CS :

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication2
{
    public partial class frmMain : Form
    {
        public frmMain()
        {
            InitializeComponent();
         
        }

       
        private void btnRecor_Click(object sender, EventArgs e)
        {
         
            RecorderForm frm = new RecorderForm();
            frm.ShowDialog();
        }

        private void btnPLayer_Click(object sender, EventArgs e)
        {
         
            FrmPlayer frm = new FrmPlayer();
            frm.ShowDialog();
         
        }

        private void frmMain_Load(object sender, EventArgs e)
        {

        }
    }
}




PlayerForm.Cs :

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using ResimİslemLib;


namespace WindowsFormsApplication2
{
    public partial class FrmPlayer : Form
    {
        public FrmPlayer()
        {
            InitializeComponent();
        }

        private void BtnAc_Click(object sender, EventArgs e)
        {
            /*click olayının baslaması ile birlikte gereken kontolleri başlatmak için  kullanıcının bir dosyayı açmak
 için dosyayı seçip aç butonun basıp basmadığını kontrol ettirmemiz gerekiyor.*/
            DialogResult Cevap= opfDosyaAc.ShowDialog();
            if (Cevap != DialogResult.OK)
                return; //okey dışında herhangi bir şeye bastıysa hiç bir işlem yapmadan çıkıyor.

            if (opfDosyaAc.FileName != "" && File.Exists(opfDosyaAc.FileName) && opfDosyaAc.FileName.EndsWith("mrd"))
            { /*(1-dosya adı boş değil ise, 2- dosya adı mevcut ise, 3- seçilen dosyanın uzantısı mrd ile bitiyor
 ise)*/
                txtPath.Text = opfDosyaAc.FileName;
                btnStart.Enabled = true;
                btnStop.Enabled = true;

            }
        }

        private void txtPath_TextChanged(object sender, EventArgs e)
        {

        }

        List<Bitmap> liste;/*sınıf bazında erişilebilir olsun diye tanımını burada yaptık*/

        private void btnStart_Click(object sender, EventArgs e)
        {

            FileStream fs = new FileStream(txtPath.Text, FileMode.Open);/*file open ile seçtiğimiz yolu 
filemode modunda ile ac*/
            BinaryFormatter bf = new BinaryFormatter();
            SaveCapture dosya  =(SaveCapture)bf.Deserialize(fs); /*tekrar class dosyasına çevirdi. deserialize 
dediğimiz an bize döndürdüğü tip objecttir.  tüm class lar deserialize edildiğinde tipleri karşılaya bilmek için 
objecttir. savecapture' e cast etmeliyiz ki  içindeki resimlere ulaşabilelim*/
            liste = dosya.GetList();
            /*player bastığımızda save ile kaydedilenmrd uzantılı dosyayı alıyor BinaryFormatter ile Serializable
 ediyor tekrar ilk bastaki formata  doldurulan formata çevriliyor. o sınıfı elde ettikten sonra da sc. GetList 
dediğimizde o sınıfıa eklenmis olan tüm sınıflar gelmiş oluo.*/

            tmrPlay.Interval = dosya.Interval; /*play tusuna bastığımız anda ki timerin zamanını dosyadan çekme 
zamanına eşitledik.*/
            tmrPlay.Enabled = true; /*tick eventinin timer'ini start clickine basıldığı an başlatmak için*/
        }

        int sira = 0;

        private void tmrPlay_Tick(object sender, EventArgs e)
        {
            pctVideo.Image = liste[sira];
            sira++;
        }

        private void btnStop_Click(object sender, EventArgs e)
        {
            tmrPlay.Enabled = false;
        }
    }
}


SaveCapture.Cs :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace ResimİslemLib
{
    [Serializable] /* kodların gömülü olarak byte türünden saklanması için serializable kodunu kullandık, bu 
sayede görüntüler programın cdi kodları arasında saklanabilecek. */
    public class SaveCapture
    {
        private int interval; /*dosyaya yazdırma frekansını ayarlamak için kullanacağız. */

        public int Interval
        {
            get { return interval; }
            set { interval = value; }
        }

        public SaveCapture()
        {
            this.interval = 300;
        }

        public SaveCapture(int interval)
        {
            this.interval = interval;
        }

        List<Bitmap> dosya = new List<Bitmap>(); /* bitmap türünden veriler saklayan generic yapısında 
dosya adında liste tanımladık. */

        public void AddList(Bitmap resim) /*listemize resim eklemek için bu metodu hazırladık*/
        {
            dosya.Add(resim);
        }

        /* dosyayı dışarıya göndermek için; */
        public List<Bitmap> GetList()
        {
            return dosya;
        }


        public void SaveFile(string path)/* path dosyanın yolunu belirticek*/
        {
            FileStream fs = new FileStream(path, FileMode.CreateNew); /* filestream sınıfı ile yeni bir dosya 
oluşturduk.*/

            BinaryFormatter bf = new BinaryFormatter(); /* binaryformatter serilaze veya deserilaze yapmamızı 
sağlar. */
            /*serilaze:classı içerisindeki veri ile diske yazmak,    deserilaze: diske yazılmış halini alıp classa 
çevirmek. */
            bf.Serialize(fs, this); /*diske yazmak için serilaze bizden işlemden sonra nereye 
kaydedileceğini(filestream) ve kaydedilecek nesneyi istiyor(class). */
            fs.Flush(); /*dosyayı yazdırıyor*/
            fs.Close(); /*kapatmaz isek stream mesgul olarak kalır program hata verir*/
        }
    }
}


ScreenCapture.Cs :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms; /*screen sınıfı forma has bir yapı olduğundan dolayı refaranslara windows formu eklememiz gerekiyor.*/


namespace ResimİslemLib
{
    public class ScreenCapture
    {
        public Bitmap CaptureScreen() {

           /*(beyaz kagıt)*/Bitmap bmp = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height );/*öncelikle width ve heigth değerlerini verip bir bitmap  ekran görüntüsü olışturmamız lazım.*/
            /*bitmapler ile çalışırken asıl işi yapan graphics sınıfıdır. ve yaptığınız değişikler bitmape yansır. o zaman bizim bir grafik nesnesi olusturup bitmapi ona dahil etmemiz gerekir.  new grafik ile grafik nesnesi olusturamiyoruz. graphics sınıfının altında statik metotlar vardır. fromlardan biri ile graphics metodu oluşturulur. bizim burda kullanacığımız image metodur. */

            /*(ressam)*/Graphics gr = Graphics.FromImage(bmp);
            /*Graphics sınıfı ekranın görüntüsünü çekebilir.*/
            gr.CopyFromScreen/*(ekran görüntüsü yakalıyor)*/(0, 0, 0, 0, new  Size(bmp.Width, bmp.Height)); /* bu metodunda 4 aşırı yüklenmiş metodu  vardır. koordinatları belirlemek için kullanılır. copyscreen ile ekranın belirli bir kısmının görüntüsü alınabilir.*/
            /* şuanda bmp de ekranın görüntüsü var. */

            return bmp;
        }
    }
}

Programı indirmek için ; 



Link:   https://hotfile.com/dl/197357241/f61aa1f/Video_Player.rar.html

Saturday, February 9, 2013

Collections ve Generic


Koleksiyonlar:

System.Collections isim uzayında yer alırlar.

Generic:

System.Collections.Generic isim uzayında yer alırlar.













Array:

Tüm genel diziler Array sınıfından türemiştir. Bu sınıfın dezantajı dizi boyutunun başlangıçta bilinmesinin gerekli olmasıdır. Önceden boyutu belli olan ve tek bir veri tipinin saklanacağı yapılar için uygundur.

int [] array = new int[10];
string []  array2 = new string[10];

ArrayList:

Dizilerin benzeridir. Tek farkı sadece object tipinden verileri saklanabilmesidir. Dolayısıyla ArrayList'e atılan veriler object tipinde değilse boxing uygulanır ve performans düşer. Boyutunun başlangıçta bilinmesi gerekmemektedir.

Add metodu ile eleman eklenir. Sort metodu ile elemanları sıralayabiliriz.

ArrayList liste = new ArrayListe();
liste.add("merhaba");
liste.add(2);

HashTable ve SortedList:

HashTable verileri Key alanın Hash kodlarına göre, SortedList ise alfabetik sıraya göre yapar. HashTable daha hızlı çalışır. Boyutun önceden bilinmesi gerekmez.

HashTable tbl=new HashTable();
tbl.Add("1", "metin");
tbl.Add("a",3)

Stack:

Son elemana ulaşmak en kolaydır. ilk elemana ulaşmak için diğer bütün elemanları çıkarmak gerekir.

Push() metodu koleksiyona eleman eklemek için kullanılır.

Pop() metodu son giren elemanı verirken bu elamanı koleksiyondan siler.

Bunun önüne geçen metod Peek() metodudur.

Stack stc=new Stack();
Stc.Push("deneme");

Stack stc = new Stack();
stc.Push("deneme");
stc.Push(120);
stc.Push(true);
stc.Pop();

Queue:

Enqueue() metodu koleksiyona eleman eklemek için kullanılır.

Dequeue() metodu koleksiyona giren eleman verirken bu elemanı koleksiyondan siler.

Bunun önüne geçen metod Peek() metodudur.

Queue sira=new Queue();

stc.Enqueue("deneme");
stc.Enqueue(120);
stc.Enqueue(true);

Generic:


List<T>:

En verimli çalışan ve en çok kullanılan Generic sınıfımızdır. ArrayList sınıfının Generic versiyonudur.

List<int> lst = new List<int>();

Lst.Add(2);
Lst.Add(192);


Dictionary<>  ve SortedList<>:


HashTable ve SortedList yapısını kullanmaktadırlar. Tek fark Key ve Value değerlerinin generic olmasıdır. Bu da her veri için iki adet boxing işleminden kurtulmak demektir. Bu da bize çok fazla performans artışı sağlar.

Dictionary<int, string> d = new Dictionary<int, string>();
d.Add(1,"metin1");
d.Add(2,"metin2");
d.Values----- Verileri dizi şeklinde getirir.


Stack<T>  ve Queue<T>:


Stack<int> stc = new Stack <int>();
stc.Push(5);
stc.Push(10);
stc.Pop();
stc.Peek();


Queue<int> q = new Queue<int>();
stc.Enqueue(5);
stc.Enqueue(10);
stc.Dequeue();
stc.Peek();






Friday, December 14, 2012

Arayüzlerin (Interface) Kullanılması (c#)


 .NET sınıfı kütüphanesinde de birçok arayüz bulunmaktadır. Her arayüz çeşitli amaçlar için yazılmıştır. Örneğin System isim alanında bulunan IDisposable arayüzü gereksiz nesne toplayıcısı (garbage collector) için gerekli olabilecek Dispose() metodunun uygulanmasını zorlar. Aynı şekilde System.Collections isim alanında bulunan IEnumarable arayüzü tanımladığımız sınıfların foreach döngü yapısı ile kullanabilmesini sağlar. IEnumarable arayüzü içindeki metotlar ilgili sınıf tarafından uygulanırsa tanımlanan bu sınıf foreach döngüsü ile kullanılabilir. Çünkü foreach döngüsü çalıştırılmaya başlanınca foreach bloğunda kullanılan sınıfn IEnurable arayüzünü uygulayıp uygulamadığını kontol edilir. Eğer bu arayüz uygulanmış ise IEnumarable arayüzündeki metotlar kullanılarak foreach döngüsü işletilir.Bu konumuzda IEnumarable arayüzünün kullanımına bir örnek vereceğiz.

IEnumarable arayüzünü uygulayan bir sınıf foreach döngü yapısı ile kullanılabildiğini söylemiştik. Tabi foreach döngü yapısı ile kullanabileceğimiz bir sınıfın yapısında dizi ya da daha sonra göreceğimiz koleksiyon tabanlı bir yapının bulunması mantıklı olur.


using System;
using System.Collections;

class Koleksiyon : IEnumerable
{
    int[] Dizi;
    public Koleksiyon(int[] dizi)
    {
        this.Dizi = dizi;
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return new ENumaralandirma(this);
    }

    class ENumaralandirma : IEnumerator
    {
        int indeks;
        Koleksiyon koleksiyon;

        public ENumaralandirma(Koleksiyon koleksiyon)
        {
            this.koleksiyon = koleksiyon;
            indeks = -1;
        }

        public void Reset()
        {
            indeks = -1;
        }
        public bool MoveNext()
        {
            indeks++;

            if (indeks < koleksiyon.Dizi.Length)
                return true;
            else
                return false;
        }

        object IEnumerator.Current
        {
            get
            {
                return (koleksiyon.Dizi[indeks]);
            }
        }
    }
}

public class MainMetodu
{
    public static void Main()
    {
        int[] dizi = {1,2,3,8,6,9,7};

        Koleksiyon k= new Koleksiyon(dizi);

        foreach(int i in k)
            Console.Write(i + " ");

        Console.ReadLine();
    }
}





Bu programı derlediğimizde ekrana

1 2 3 8 6 9 7

yazıldığını göreceğiz.

Programda neler olup bittiğine göz atmak gerekirse, Koleksiyon isimli bir sınıfın yapısındaki Dizinin eleman değerlerini foreach döngüsü ile elde etmek için Koleksiyon sınıfı System.Collections isim alanında bulunan IEnumarable arayüzünü uyguluyor. Dolayısıyla IEnumarable arayüzündeki bütün metotları uygulamalıdır. IEnumerable arayüzünde sadece

IEnumerator GetEnumerator();

metodu ile bildirilmiştir. Bu metot dizinin içerisinde dolaşmak için gerekli olan IEnumerator referansına geri dönmektedir. Bu yüzden bu metot aşağıdaki gibi yazılmıştır.

IEnumerator IEnumerable.GetEnumerator()
{
  return new Enumaralandırma(this);
}

GetEnumerator() metodunun geri dönüş değeri için IEnumerator arayüzünden türetilmiş IEnumaralandırma sınıfı bildirilmiştir. IEnumerator arayüzündeki metot ve özellikler Koleksiyon nesnesi içindeki dizinin elemanlarına erişmek için kullanılacaktır. IEnumerator arayüzünde bulunan üye elemanlar aşağıdaki gibidir.

object Current{
get;
}

bool MoveNext();

Void Reset();

Bu iç elemanında IENumaralandırma sınıfında bildirilmesi gerekir. Current özelliği koleksiyon nesnesinin herhangi bir andaki değerini gösterir. Sade get bloğunu bildirmek yeterlidir. MoveNext() metodu dizi koleksiyon dizisi içinde bir sonraki elemana geçmek için kullanılır. Eğer bir sonraki elemana geçilemiyorsa false deperini geri döner. Reset() metodu ise koleksiyon dizisini herhangi bir andaki değerini ilk elemandan önceki elemana çeker. Yani dizinin indeksi -1 olur.

IEnumaralandırma sınıfının bir tane yapıcı metodu vardır. Bu yapıcı metot ile üzerinde işlem yapılacak Koleksiyon nesnesi alınmaktadır. Yapıcı metot ile aynı zamanda ENumarandırma sınıfındaki indeks değişkenide -1 değerine çekiliyor. Reset() metodunda ise indeks değişkeni bir artırılıyor. Eğer indeks değişkeninin  yeni değeri dizinin boyutundan büyükse false değerini geri dönmektedir. Current özelliğinin object olduğuna dikkat edin. Eper bu özellik object türünden olmasaydı mğmkğn olabilecek tür dönüşümlerini hesaba katmazsak bütün işlemleri sadece Current özelliği ile aynı türden olan diziler üzerinde yapabilirdik.

Açık (Explict) Arayüz Uygulama


C# dilinde arayüzleri uygulamanın bir yolu daha vardır. Explicit Interface Implementation. Bu yöntem daha önce bahsedilen yöntemlerin aşağıdaki kısımlarından kaynaklanmaktadır.

- Açık arayüz uygulama yöntemi ile istenirse türeyen sınıflarda arayüzde bulunan üye elemanlar açık bir şekilde nesneler tarafından erişilemez hale getirilebilir. İlgili üye elemanlarına sadece arayüz referansları ile erişilmesi sağlanır.

- Birden çok arayüz uygulandığı durumlarda eğer aynı isimli üye elemanlar varsa isim çakışmasının önüne bu yöntemle geçilebilir.

Açık arayüz uygulaması yapmak için arayüzün üye elemanları arayüz isimleri ile beraber belirtilir. Aşağıda buna bir örnek verilmiştir.

using System;
using System.Collections.Generic;
using System.Text;

namespace explicitinterfaceimplemetantion
{
  class Program
  {
     static void Main(string[] args)
     {
        Kedi k= new Kedi();
       
        ((IMEmeli).k).Konus();
     }
  }

interface IMemeli
{
   void Konus();
}

class Kedi : IMemeli
 {
   void IMemeli.Konus()
   {
      Console.WriteLine("miyav");
   }
 }
}

Yukarıdaki örnekte de görüldüğü üzere Konus() metodunun çağrılabilmesi için IMemeli arayüzü referansına çevrilmesi gerekiyor. Direkt Kedi nesneleri üzerinden Konus() metodu çağrılamayacaktır. Böylece sınıf nesneleri için arayüz üye elemanları private gibi davranmaktadır. Normal yöntemle bunu yapmak mümkün değildir.

Wednesday, December 12, 2012

Arayüz (Interface) Referansları (c#)


Arayüzler ile referans oluşturulabilir. Bir arayüz referansı tek başına bir anlam ifade etmez. Ancak arayüz
referanslarına kendisini uygulayan herhangi bir sınıf nesnesinin referansı atanabilir. Bu durumda arayüz
referansı ile arayüzde bulunan metot ya da özellikler hangi sınıf referansı tutuluyorsa o sınıf türünden bir
nesne için çağırılabilir.
Bu özelliğine örnek vermek gerekirse aşağıda ArayuzRef arayüzünü uygulayan iki sınıfın bildirimini görüyoruz.
Main() metodu içinde ise ArayuzRef referansına bu iki sınıfın nesne referanslarının nasıl aktarıldığını ve bu
referans üzerinden sınıflardaki metotların nasıl çağrıldığını görüyoruz.

using system;

interface ArayuzRef
{
  void metot1();
}

class Sinif1 : ArayuzRef
{
  puplic void metot1(){
  Console.WriteLine("Ben Sinif1'in metoduyum");
  }
}

class Sinif2 : ArayuzRef
{
  puplic void metot1(){
  Console.WriteLine("Ben Sinif2'nin metoduyum");
}

puplic class MainMetodu
{
  puplic static void Main()
  {
    ArayuzRef a;

Sinif1 sinif1 = new Sinif1();
Sinif2 sinif2 = new Sinif2();

a = sinif1;
a.metot1();

a = sinif2;
a.metot1();
   }
}

Programı derleyip çalıştırdığımızda ekrana

Ben Sinif1'in metoduyum
Ben Sinif2'nin metoduyum

yazacaktır. Arayüzlerdeki referans aktarma işlemi ile kalıtımda gördüğümüz temel sınıf referansına türeyen sınıf referansı aktarma işlemi ile aynıdır.

Monday, December 10, 2012

Arayüzlerin (Interface) Uygulanması (c#)


 Şimdi bir sınıfın belirlediğimiz bir arayüzün nasıl uygulandığını inceleyeceğiz.
Arayüzlerin uygulanması, sınıfların türetilmesi ile aynı şekilde yapılır. Arayüz uygulamada, arayüzler türetmedeki temel sınıf yerine geçer. Buna göre IArayüz'ü uygulayan Sayılar sınıfı aşağıdaki gibi bildirilir.

class Sayılar : Iarayuz
{
  //uygulanacak elemanlar
}

Sayılar sınıfı bu şekilde IArayuz'den türetildiğinde IArayuz'deki bütün üye elemanları uygulanmalıdır.

Buna göre Sayılar sınıfı IArayuz'ü ile aşağıdaki gibi bildirilebilir.

interface IArayuz
{
 int BirSonraki();
 void Sıfırla();

 int Deger
 {
  get;
  set;
 }

 int this [this indeks]
 {
 get;
 }
}

class Sayılar : IArayuz
{
 puplic int BirSonraki()
 {
   //metot gövdesi
 }

puplic void Sıfırla()
{
  //metot gövdesi
}

puplic int Deger
{
get
{
  //get bloğu
}

set
{
 //set bloğu
}
}

puplic int this[this indeks]
{
get
{
  //get bloğu
}

set
{
 //set bloğu
}
}
}

 Sınıflar arasında çok türetme olmamasına rağmen sınıflar birden fazla arayüzüde uygulayabilir. Uygulanacak
arayüzler virgül ile belirtilir. Örneğin IDisposable ve System.Collecitons isim alanında bulunan IEnumarable
yüzünü uygulayan sayılar sınıfı aşağıdaki gibi bildirilebilir.

using System;
using System.collections;

class Deneme : IDisposable, IEnumerable
{
  //Sınıf elemanları
}

Bir arayüzdeki elemanlar içsel olarak puplic olduğu için arayüzü uygulayan sınıfın arayüzdeki elemanları puplic
olarak bildirilmemelidir.

Bir arayüzü uygulayan sınıfın, sadece arayüzdeki elemanlara sahip olabileceği anlamına gelmez. Aynen türetmede
olduğu gibi arayüzdeki elemanların dışında istenildiği kadar yeni eleman eklenebilir.

Sınıflar birbirlerinden nasıl türetilebiliyorsa Arayüzler de birbirlerinden türetilebilir. Temel arayüzdeki bütün
elemanlar türeyen arayüze aktarılır. Böylece istediğimiz kadar eski arayüzü kullanarak daha geniş arayüzleri
oluşturabiliriz. Aşağıda iki arayüzün türetilmesine ilişkin bir örnek verilmiştir.

interface TemelArayuz
{
 void Metot1();
}

interface TureyenArayuz : TemelArayuz
{
  void Metot2();
}

Arayüzden yeni bir Arayüz türetildiğinde dikkat edilmesi gereken hususlar:

Bu kullanım ile TemelArayuz'ü uygulayan bir sınıf sadece Metot1'i uygulamalı iken TureyenArayuz'ü uygulayan bir
sınıf hem Metot1() hem de Metot2()'yi uygulamalıdır. Aksi halde derleme hatası alınır. Sınıflardan farklı olarak
arayüzleri birden fazla arayüz ile türetebiliriz. Örneğin aşağıdaki Arayuz3 bildirimi tamamen geçerlidir.

interface Arayuz1
{
  void Metot1();
}

interface Arayuz2
{
  void Metot2();
}

interface Arayuz3: Arayuz1, Arayuz1
{  void Metot3();
}

Arayüzleri türetirken new anahtar sözcüğü kullanılarak temel arayüzdeki bir eleman gizlenebilir. Bu şekilde
türeyen arayüzde temel arayüzdeki bir elemanla aynı isimli eleman bildirilebilir.

interface Arayuz1
{
  void Metot1();
}
interface Arayuz2 : Arayuz1
{
 new void metot1();
}

Peki bu durumda sadece Arayuz2'yi uyguluyan bir sınıfta Metot1() metodu uygululandığında geçerli bir bildirim olur mu?
 Hayır, çünkü Arayüz1'deki Metot1() metodu gizlenmiş olsa da kalıtım yolu ile Arayuz2'ye aktarılmıştır. Bu yüzden Arayuz2'yi uygulayan bir sınıf hem Arayuz1.Metot1() hem de Arayuz2.metot1() metodunu uygulamak zorundandır. Bunun için Arayuz_adı.Metot_adı ile hangi arayüzdeki metodu uyguladığımızı bildirmeliyiz. Örneğin;

class Deneme: Arayuz2
{
  void Arayuz1.Metot1();
  {
  }

  void Arayuz2.Metot1();
  {
  }
}

Deneme sınıfından bir nesne üzerinden Metot1() metoduna erişmemiz mümkün değildir, çünkü

deneme d= new deneme();
d.Metot1();

deyimiyle hangi arayüze ilişkin metodun çağrıldığı belirsizdir. Bu yüzden yukarıdaki gibi bir kullanım hatalıdır.

O halde Arayuz1.Metot1() ve Arayuz2.Metot1() metotları sadece Deneme sınıfında aşağıdaki gibi tam yolu
belirtilerek kullanılabilir.

void Arayuz2.Metot1()
{
   Arayuz1.Metot1();
}



Sunday, December 9, 2012

Arayüzler (Interface) (c#)


Özet metotlar ile bir özet metodun bulunduğu sınıftan türeyen bir sınıfın mutlaka bu özet metodu devre dışı bırakıp kendine göre uygulaması gerekirdi. Burada amaç aslında bir sınıfın neye benzediğini tespit etmekti. Özet metotlar sayesinde biliyoruz ki bir önceki temel sınıftan türeyen tüm sınıflarda özet metot uygulanmıştır. Bu da tek bir arayüzle birçok iş yapabileceğimiz anlamına gelir. Yani özet sınıfının bir kısım elemanları kendisinden türeyecek sınıflara arayüz niteliği taşımaktadır. Ayrı bir veri türü olan Interface ise tamamen diğer sınıflar için arayüz görevini taşır. Arayüzlerin bütün metotları ve özelliklerinin özet olarak bildirilmiş sınıflardan çok fazla farkı yoktur. Dolayısıyla arayüzlerdeki metotların ve özelliklerin gövdesi yazılamaz. Kısaca arayüzler, kendisini uygulayan sınıfların kesin olarak içerceği özellikleri ve metotları belirler.

 Arayüzler kişisel uygulamalarda pek fazla kullanılmaz ancak özellikle birkaç firmanın ya da programcının üzerinde çalıştığı projelerde ortak bir zemin oluşturabilmek için arayüzlerden faydalanılır.

Arayüz bildirimi:

Arayüzler, interface anahtar sözcüğü kullanılarak bildirilir. Bir arayüzde özellik, indeksleyici, metot, temsilci ve olay bildirimi yapılabilir. Arayüz isimleri geleneksel olarak I harfi ile başlar.

Arayüz bildirimi ile ilgili çeşitli kısıtlamalar vardır.

*Arayüzdeki elemanları statik olarak bildiremeyiz.
*Arayüzdeki eleman bildirimleri içsel olarak puplic oldukları için ayrıca bir elemanı erişim belirleyici ile bildirmek yanlıştır.
*Arayüzler herhangi bir üye değişken içeremez.
*Arayüzlerde yapıcı ve yıkıcı metotlar tanımlanamaz ya da bildirilemez.

Aşağıda iki metot, bir özellik ve bir indeksleyici bildirimi içeren arayüz tasarlayalım.

interface IArayuz
{
  int BirSonraki();
  void Sıfırla();
 
  int Deger
  {
   get;
   set;
  }
 
  int this[int indeks]
  {
  get;
  }
}

Bu arayüzü uygulayan bir sınıfta Arayüzde bulunan bütün elemanların uygulanması gerekir. Deger özelliğinin hem get hem de set blokları olmasına karşın indeksleyicinin sadece get bloğu vardır. Buna rağmen bu arayüzü uygulayacak sınıfta bildirilen indeksleyicinin hem get hem de set bloğu ya da sadece get bloğu olabilir, fakat sadece set bloğu olamaz.

Arayüzlerdeki hatalı kullanımları inceleyelim.

*Asağıdaki Arayüz bildiriminde metot puplic erişim belirleyicisi ile bildirildiği için geçersizdir.

  interface IArayuz
  {
    puplic void Metot();
  }


*Aşağıdaki Arayüz bildiriminde statik metot bildirimi yapıldığı için geçersizdir.

  interface IArayuz
  {
    static void Metot();
  }

 
*Aşağıdaki arayüz bildiriminde ise üye değişkenin bildirilmesi arayüzü geçersiz kılmıştır.

  interface IArayuz
  {
    int a;

    void Metot();

int Ozellik
{
get;
}
  }
 

Saturday, December 1, 2012

Özet (Abstract) Sınıflar (c#)


 Nesne tabanlı programlamada sınıf hiyerarşisi oluştuturken bazen hiyarerşinin en tepesinde bulunan sınıf türünden nesnelerin progmcılar için pek anlamı olmayabilir. Hiyerarşinin en tepesinde bulunan sınıfın kendisinden türetilecek olan alt sınıflar için ortak bir arayüz görevi görmesini isteyebiliriz. Örneğin Memeli sınıfında bulunan Konus() isimli metot çağrıldığında yapacağı iş belli değildir. Yani hangi türdenmemeli türünde konuşacağı belli değildir. Eğer Konus() Metodunu temel sınıfımızda tanımladan direkt kuş, kedi gibi alt sınıflarda tanımlarsak bu sefer Memeli sınıfından türeyecek sınıfların çok biçimliliği desteklememesi söz konusu olacaktır. Bunun için çözüm olarak, Memeli sınıfında Konus() metodu bildirilsin ancak herhangi bir işlevi özelliştirmesin, Memeli sınıfından türeyecek diğer sınıflar için bir arayüz görevi görsün. İşte bu amaçla oluşturulan metotlara ve sınıflara özet metot yada özet sınıf deriz.

   Özet sınıflar ya da özet metotlar abstract anahtar sözcüğü kullanılarak tanımlanır. Temel sınıf içerisinde bildirilen özet(abstract) metotların temel sınıf içerisinde gövdesi yoktur, sadece tanımlaması yapılır. Ancak bu temel sınıftan türeyen bütün sınıflar bu metodu override anahtar sözcüğü ile devre dışı bırakılmalıdır. Özet metotlar zaten sanal olarak görev yaptıkları için virtual anahtar sözcüğü ile sanal olarak tanımlamamıza gerek yoktur.

 Özet metotların Tanımlanması


 Özet sınıflar metot bildiriminin başına abstract anahtar sözcüğünün konulması ile bildirilir.

 abstract puplic void OzetMetot();
 /*Görüldüğü üzere metodumuzun tanımlanması " ; " ile sonlandırılmıştır. Yani metodumuzun gövdesi yoktur.*/

 abstract puplic void OzetMetot(){
 }

 şeklinde gövdesini boş bıraksakta bir metot tanımlamamız yasaklanmıştır.

 Özet sınıfların tanımlanması

  Özet sınıflarda abstract anahtar sözcüğü kullanılarak bildirilirler.  Bir özet sınıf türünden nesneler
 tanımlanamaz. Özet sınıflar ancak kendilerinden türeyen alt sınıflar için arayüz görevi görür.

 abstract class OzetSinif
 {
 }

 Özet sınıflar temel sınıfın tek başına anlamlı bir nesneyi ifade etmediği durumlarda kullanılır.
 Özet sınıfları kullanabilmemiz için özet sınıf türünden yeni sınıflar oluşturmalıyız.


 Her ne kadar Özet sınıftan nesler üretemesekte, özet sınıftan türeyen sınıf nesneleri üzerinden özet sınıfa
 ait yapıcılar kullanılarak özet sınıfın değişkenleri değiştirilebilir. Aşağıda Memeli sınıfından türeyen Kedi
 sınıfından nasıl nesnelerin oluşturulduğunu ve kullanıldığını göreceğiz.

 Using System;

 abstract class Memeli /*Özet sınıf tanımlandı. */
 {
     Puplic double en;
Puplic double boy;

puplic Memeli(double en, double boy)
{
this.en=en;
this.boy=boy;
}
 }

 class Kedi : Memeli
 {
    String Turu;
    puplic Kedi(string turu, double en, double boy) :  base(en,boy)
    {
      this.Turu=turu;
    }
 }

 class MainMetodu
 {
    static void Main()
{
 Kedi kedi = new Kedi("van", 5, 15);
 console.writeline("kedinin eni: "+ kedi.en);
 console.writeline("keninin boyu: " + kedi.boy);


Temel sınıfta oluşturulan abstract metotlar türeyen sınıflarda devre dışı bırakılmalır. Eğer abstract metot
devre dışı bırakılmaz ise derleyici hata verecektir.
Örneğin;

 Using System;

 abstract class Memeli /*Özet sınıf tanımlandı. */
 {
     Puplic double en;
Puplic double boy;

puplic Memeli(double en, double boy)
{
this.en=en;
this.boy=boy;
}

abstract puplic void konus(); /* özet metodumuzu tanımladık. Özet metodumuz Memeli sınıfından türetilecek olan alt sınıflar tarafından devre dışı bırakılmalıdır.*/
 }

 class Kedi : Memeli
 {
    String Turu;
    puplic Kedi(string turu, double en, double boy) :  base(en,boy)
    {
      this.Turu=turu;
    }
 }
 Bu programda derleyici " Kedi türediği sınıfın özet metodu olan Memeli.Konus() metodunu devre dışı
 bırakmamıştır" hatası verecektir. Hatayı düzetlmek için Özet sınıftan türetilen Kedi sınıfı içerisinde
 Özet metot olan Konus Metodunu  Override void Konus()  Tanımlamasıyla devre dışı bırakılmalıdır.


 Metotlar ve sınıflar gibi özellikler de özet olarak bildirilebilir. get ve set bloğu olan bir özet özellik
 aşağıdaki gibi tanımlanır.

 abstract class OzetOzellik
 {
 abstract puplic int A
 {
   get;
   set;
 }
 }

 Ozet ozellik sınıfından türeyen bir sınıf A özelliğini hem get hem de set blokları ile birlikte uygulamak
 zorundadır. Eğer temel sınıfta get yada set bloklarından herhangi biri bildirilmiş olsaydı türeyen sınıfta
 sadece ilgili blok yazdırılırdı.

 abstact class Temel
 {
   abstract puplic int A
   {
    get;
set;
}
  }

 class Tureyen : Temel
 {
 int a;

  puplic override int A
  {
  get{
   return a;
   }
 }

 Özet sınıflar ve metotlar ile genel özellikler

 1.Özet sınıflar türünden nesneler tanımlanamaz.

 2.Özet sınıflar, özet metotlar içerebilirler. Özet metotlar ancak özet sınıfların içinde bildirilebilir.

 3.Özet sınıflar ealed anahtar sözcüğü ile işaretlenemezler.

 4.Özet bir sınıftan türeyen sınıflar temel sınıftaki bütün özet metotları uygulamalıdır. Yani metodun gerçek
 gövdesi türeyen sınıflarda yazılmalıdır.

 5.Bir özet metot ancak bir özet içinde bildirilebilir.

 6.Bütün özet sınıflar içsel olarak sanaldır. bu yüzden virtual olduklarını belirtmeye gerek yoktur.

 7.Özet metotlar türeyen sınıfta mutlaka bildirilmelidir.

 8.Statik metotlar özet olarak bildirilemez.

 9.Sınıflarda özet özellikler de bildirilebilir, türeyen sınıflarda bu özet özellikler override anahtar
 sözcüğü ile tekrar bildirilmelidir.

 10.Bir özet sınıf içinde özet olmayan metotlar da bildirilebilinir. Ancak bir sınıf içinde özet metot bildirilmiş
 ise o sınıf özet olarak tanımlanmalıdır.

Friday, November 2, 2012

Çok Biçimlilik(Polymorphism) (c#)


Tek bir metot ile birçok sınıfa ait farklı versiyondaki metotlar çağrılabilmektedir. Üstelik bu işlem aynı
nesne üzerinden olmaktadır. Bir nesnenin bu şekilde çoklu özellik göstermesine çok çeşitlilik(polymorphism)
denilmektedir.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Polymorphism
{
    class Sekil
    {
        public double Boy;
        public double En;

        public Sekil(double boy, double en)  /* kurulurken boy ve en değerlerini alan constructor yazdık */
        {
            this.Boy = boy; /* base sınıfta sadece boş constructor olduğunda kullanılması yaygındır.*/
            this.En = en;
        }
        public Sekil()
        {
        }
        virtual public double Alan() /*sanal alan metodu yazdık. türeyen sınıfta Alan() metodu varsa buradaki 
                                                  ezilecektir.*/
        {
            return 0;
        }
    }

    class Dortgen : Sekil /* sekil sınıfından dortgen sınıfını türettik*/
    {
        public Dortgen(int boy, int en)
            : base(/*boy,en*/)       /* alınan değerleri türetilen sınıftaki   değişkenlere gönderiyor.
                                                 Base.Boy tanımlamamıza gerek olmuyor. */
     /*eger base sınıfta (boy,en) constructorı yoksa bunu kullanamayız.*/
         
        {
            base.Boy = boy; /* base sınıfta sadece boş constructor olduğunda kullanılması yaygındır.*/
            base.En = en;
        }

        public override double Alan()  /* eger kurulan sınıf dortgen olursa sekil sınıfındaki Alan() metodu yerine 
                                                       buradaki Alan() çağırılacak*/
        {
            return En * Boy;
        }

    }
    class Ucgen : Sekil
    {
        public Ucgen(int boy, int en)
            : base(boy, en) /* eger base sınıfta (boy,en) constructorı yoksa bunu kullanamayız.*/
        {
        }

        public override double Alan()  /* eger kurulan sınıf dortgen olursa sekil sınıfındaki Alan() metodu yerine 
                                                      buradaki Alan() çağırılacak*/
        {
            return En * Boy / 2;
        }
    }

    class MainMetodu
    {
        public static void AlanBul(Sekil sekil)
        {
            Console.WriteLine("seklin alanı: " + sekil.Alan());
        }
        static void Main()
        {
            Ucgen ucgen = new Ucgen(10, 50);
            AlanBul(ucgen);

            Dortgen dortgen = new Dortgen(10, 50);
            AlanBul(dortgen);

            Sekil sekil = new Sekil(10, 50);
            AlanBul(sekil);

            Console.ReadLine();
        }
       
    }
}


ekran çıktısı:

250
500
0
   şeklinde olacaktır.
 
   Gördüğümüz gibi statik AlanBul() metodu Sekil türünden bir nesne beklemesine rağmen Sekil Türünden
   türeyen Ucgen ve Dortgen nesnelerini de kabul etmektedir. Üstelik bu Ucgen Ve Dortgen nesneleri metodun
   parametresi olan Sekil nesinesine aktarilmasına rağmen Ucgen ve Dortgen sınıflarındaki Alan() metotları
   çağrılabilmiştir. Bunu sağlayan da süphesiz Alan() metodunun sanal olarak bildirilmesi ve Türeyen
   sınıflarda bu metodunun devre dışı bırakılmasıdır.
 
   Türeyen sınıflar, temel sınıflardaki sanal metotları devre dışı bırakmak zorunda değildir. eğer türeyen
   sınıfta ana sınıftaki sanal metodu ezecek bir sınıf tanımlanmadıysa türeyen sınıf için de ana sınıftaki
   sanal metot geçerli olur. Aşağıda örneklendirmek gerekirse;
 
   class Dortgen : Sekil
   {
     puplic Dortgen(int boy, int en):base (boy,en)
{
}
}
 Dortgen metodumuz bu şekilde olsaydı
 Dortgen dortgen= new Dortgen(10,50);

 dortgen.Alan()  için ana sınıftaki yani Sekil sınıfındaki virtual tanımlanan Alan() metodu geçerli
 olacaktı.

 Hiyerarşik sınıf yapılarında bu kural geçerlidir. Hiyerarşik yapılardaki sınıflarda yukarıdaki gibi
 bir kullanım söz konusu olursa en alttan en üste doğru Alan() metodunun ilk devre dışı bırakıldığı
 sınıfa ait metot çağırılır.


 Çok çeşitlilik ve metotların devre dışı bırakılması ile ilgili öğrendiklerimizi pekiştirmek gerekirse;


 1. Eğer metot sanal olarak bildirilmemişse, derleyici nesnelerin tür bilgisinden faydalanarak derleme
 zamanında hangi metodun çağrılcağını bilir.

 2. Eğer metot sanal olarak bildirilmiş ise, derleyici derleme aşamasında ürettiği kod ile çalışma
 zamanında referansın türüne göre ilgili sınıfın devre dışı bırakılmış metodunu çağırır.

 3. Hangi metodun çağıracağının çalışma zamanında belirlenmesine geç bağlama(late binding)
          denilmektedir.

 4. Sanal metot bildirmek için virtual anahtar sözcüğü kullanılır.

 5. Türeyen sınıfta, temel sınıftaki sanal metodu devre dışı bırakmak için override anahtar sözcüğü
 kullanılır.

 6. Türeyen sınıfta devre dışı bırakılan metotların temel sınıftaki sanal metotların ismi aynı olamk
 zorundadır.

 7. Türeyen sınıfta devre dışı bırakılan metotların parametrik yapısı temel sınıftaki parametrik yapısı
 ile aynı olmak zorundadır.

 8. Statik metotlar sanal olarak bildirilemez.

 9. Türeyen sınıflar, temel sınıftaki sanal metotları devre dışı bırakmak zorunda değildir. Bu durumda
 temel sınıf referansı üzerinden temel sınıfa ait metot çağırılır.

Wednesday, October 31, 2012

Sanal Metotlar Örneği (c#)


Temel Ev Sınıfı:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

   /*kalitimda türetilen classların namespaceleri aynı olması tek bir referans üzerinden erişmemiz için kolaylık 
      sağlar.*/
namespace emlakci
{
    public class Ev
    {
        private int odasayisi;
        public int Odasayisi
        {
            get { return odasayisi; }
            set { odasayisi = value; }
        }
        private int katno;

        public int Katno
        {
            get { return katno; }
            set { katno = value; }
        }
        private int alan;

        public int Alan
        {
            get { return alan; }
            set { alan = value; }
        }
        private string semt;

        public string Semt
        {
            get { return semt; }
            set { semt = value; }
        }

        public Ev()
        {
        }
        public Ev(int odasayisi, int katno, string semt, int alan)
        {
            this.odasayisi = odasayisi;
            this.katno = katno;
            this.semt = semt;
            this.alan = alan;
        }

        /* virtual sanal anlamına gelir. virtual tanımlanan metotlar override ile tanımlanan metotlar tarafından 
          ezilebilir.*/
        public virtual string EvGoruntule()
        {
            return string.Format(" Odasayisi: {0} Katno: {1} Alan: {2} Semt: {3}", odasayisi, katno, alan, semt);
        }
    }
}


Türeyen Satılık Ev Sınıfı:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

/*kalitimda türetilen classların namespaceleri aynı olması tek bir referans üzerinden erişmemiz için kolaylık sağlar.*/
namespace emlakci
{
    public class satilikev : Ev
    {
        private int fiyat;

        public int Fiyat
        {
            get { return fiyat; }
            set { fiyat = value; }
        }
        private int kapora;

        public int Kapora
        {
            get { return kapora; }
            set { kapora = value; }
        }

        public satilikev(int odasayisi, int katno, int alan, string semt, int fiyat, int kapora) : base()
        {
            base.Alan = alan;
            base.Katno = katno;
            base.Semt = semt;
            base.Odasayisi = odasayisi;
            this.fiyat = fiyat;
            this.kapora = kapora;
        }

        /*override ezmek anlamına gelir. Base sınıfındaki virual tanımlanmış metodun yerine önceliği alır. Artık
          virtual metot yerine aktif
         * olan sınıf override sınıfı olur. base sınıfındaki virtual metodu yerine öncelikli olarak override sınıflarla 
           işlem yapılır. eğer 
         * override sınıfı bulunmaz ise virtual sınıf ile işleme devam edilir. */
        /* override tanımladığımız metot türetilen sınıftaki virtual metodu yerine çağrışır. bir anlamda virtual 
           metodunu ezer. */

        public override string EvGoruntule()
        {
            return base.EvGoruntule() + " Fiyat: " + fiyat +  " Kapora: " + kapora;
        }
    }
}

Türetilen Kiralık Ev Sınıfı:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

/*kalitimda türetilen classların namespaceleri aynı olması tek bir referans üzerinden erişmemiz için kolaylık sağlar.*/
namespace emlakci
{
    public class kiralikev:Ev
    {
        public kiralikev()
        {
        }

        public kiralikev(int odasayisi, int katno, int alan, string semt, double kira) : base(/*aşağıdaki tanımları 
                                                                                                                              burada yapabilirdik.*/)
        {
           /*yukarıdaki boş base constructori dolu olsaydı tekrardan base ile ataması yapmamıza gerek 
             kalmayacaktı. */
           base.Odasayisi = odasayisi;
           base.Katno = katno;
           base.Alan = alan;
           base.Semt = semt;
           this.kira = kira;
         
        }

        public double kira;
        public double depozito;

        /*override ezmek anlamına gelir. Base sınıfındaki virual tanımlanmış metodun yerine önceliği alır. Artık 
         virtual metot yerine aktif
         * olan sınıf override sınıfı olur. base sınıfındaki virtual metodu yerine öncelikli olarak override sınıflarla 
            işlem yapılır. eğer 
         * override sınıfı bulunmaz ise virtual sınıf ile işleme devam edilir. */
        /* override tanımladığımız metot türetilen sınıftaki virtual metodu yerine çağrışır. bir anlamda virtual 
         metodunu ezer. */
        public override string EvGoruntule()
        {
            return base.EvGoruntule() + " Kira " + kira + " Depozito: " + depozito;
        }
    }
}




Main Sınıfı:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using emlakci;

//Not: base sınıf üzerinden kalıtım sınıflarına erişebilme:

namespace kalitimsinifi
{
    class Program
    {
        static void Main(string[] args)
        {
            /*kalitim tüm sınıfları base sınıf üzerinden kullanabilme imkanı verir.
            fakat o sınıflara has alanı görmek için gerçek tipine cast etmemiz gereklidir. */

            Ev ev1 = new kiralikev(1, 1, 1, "1", 1);
            Ev ev2 = new satilikev(2, 2, 2, "2", 2, 2);
            Ev ev3 = new kiralikev(3, 3, 3, "3", 3);
            Ev ev4 = new satilikev(4, 4, 4, "4", 4, 4);
            kiralikev ev5 = new kiralikev(5, 5, 5, "5", 5);
            satilikev ev6 = new satilikev(6, 6, 6, "6", 6, 6);

            Ev[] evler = new Ev[6];
            evler[0] = ev1;
            evler[1] = ev2;
            evler[2] = ev3;
            evler[3] = ev4;
            evler[4] = ev5;
            evler[5] = ev6;
         
            for (int i = 0; i < evler.Length; i++)
            {
                Console.WriteLine(evler[i].EvGoruntule());

                if (evler[i] is kiralikev)
                {
                   /* kiralikev sinifindan bir nesne tanımlıyoruz ve bu nesneye evler[i] nesnesini (kiralikev) 
                    operatörüyle casting edip atıyoruz.)*/

                   kiralikev ke = (kiralikev)evler[i];

                   /* NOT: (evler[i] as kiralikev).depozito deyimi casting ile aynı görevi görür. */
                   Console.WriteLine(" depozito: "+ ke.depozito);
                }
            }

            Console.ReadLine();
        }

    }
}

Sanal Metotlar (c#)


Şu ana kadar bir nesne üzerinden çağırdığımız metotların tamamı derleme zamanında belirgindi. Yani derleme
aşamasında hangi nesne üzerinden hangi metotların çaığrabileceği belliydi. Sanal metotlar yardımıyla çalışma
zamanında metot seçme işinin nasıl olduğunu inceleyeceğiz.

Sanal metotlar temel sınıflar içinde bildirilmiş ve türeyen sınıflar içinde de tekrar bildirilen metotlardır.
Sanal metotlar nesne yönelimli programlama tekniğindeki çok biçimliliği(polimorphism) uygulayan yapılardır.
Temel sınıfta bir sanal metot bildirildiğinde bu temel sınıflar, temel sınıftaki sanal metodu devre dışı bırakarak
kendi metot gövdelerini oluşturabilirler.

Sanal metotlar sayesinde Temel sınıf türünden bir referansa türeyen sınıf referansları aktarıldığında, temel
sınıf referansı üzerinden kendisine aktarılan türeyen sınıfın sanal metodu çağrılabilir. Eğer türeyen sınıf
sanal metodu devre dışı bırakmamış ise temel sınıftaki sanal metot çağrılır. Çağrılan metodun hangi türe ait
olduğu çalışma zamanında belirlenir. Metotların bu şekilde çalışma zamanında belirlenmesine geç bağlama
(late binding) denilmektedir.

Sanal metotlar virtual anahtar sözcüğü kullanılarak bildirilir. Bu anahtar sözcük, metot bildirimin başına
eklenirse soyut metotlar bildirilmiş olur. Türeyen sınıfta, temel sınıftaki soyut netotları devre dışı
bırakmak için ise override anahtar sözcüğü kullanılır.


Sanal metotların etkin kullanılığı bir örnek;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SanalMetotlar
{
    class Memeli
    {
        public double Boy;
        public double Agirlik;

        public Memeli(double boy, double agirlik)
        {
            this.Boy = boy;
            this.Agirlik = agirlik;
        }

        virtual public void Konus()  /* Türetilen sınıflar ile işlem yapılacağı zaman, Konus() metodu 
                                    türetilen sınıfta override anahtar sözcüğü ile tanımlanmış ise
                                                   Türetilen sınıftaki metot çağıralacak. */
        {
            Console.WriteLine("ben konusamam");
        }
    }

    class kedi : Memeli
    {
        public string Turu;
        public kedi(string turu, int boy, int agirlik)
            : base(boy, agirlik)
        {
            this.Turu = turu;
        }

        override public void Konus()  /* Kedi sınıfı ile işlem yapılacağı zaman Base sınıftaki virtual ile
                                tanımlanan Konus() metodu yerine buradaki konus() metodu çağıralacak.*/
                               
        {
            Console.WriteLine("Ben bir kediyim");
        }
    }

    class koyun : Memeli
    {
        public string Turu;
        public koyun(string turu, int boy, int agirlik)   : base(boy, agirlik)  /* alınan değerleri türetilen sınıftaki  
                                                          değişkenlere gönderiyor. Base.Boy  tanımlamamıza gerek kalmıyor */
        {
            this.Turu = turu;
        }

        override public void Konus() /* Koyun sınıfı ile işlem yapılacağı zaman Base sınıftaki virtual ile
                                tanımlanan Konus() metodu yerine buraki konus() metodu çağıralacak.*/
        {
            Console.WriteLine("Ben bir koyunum");
        }
    }

    class MainMetodu
    {
        static void Main()
        {
            Memeli memeli1 = new Memeli(20, 30);
            kedi kedi1 = new kedi("Van", 10, 15);
            koyun koyun1 = new koyun("keçiören", 60, 80);

            memeli1.Konus();


            memeli1 = kedi1;
            memeli1.Konus();


            memeli1 = koyun1;
            memeli1.Konus();

           

            Console.ReadLine();

        }
    }
}

ekran çıktısı;

ben konusamam
ben kediyim
ben koyunum  

 Şeklinde olacaktır. Kedi ve Koyun nesneleri ait referans aktarılmasına rağmen çalışma zamanında bu Memeli
 referansı üzerinden Konus() metodunu çağırdığımızda Memeli sınıfındaki Konus() metodu yerine kendisine
 atanan sınıflara ait Konus() metotları çağrılmıştır.

 Sanal metotlar sayesinde temel sınıf referanslarına türeyen sınıf referansları atandığında, temel sınıf
 referansı üzerinden türeyen sınıfa ait metotları çağırabilmekteyiz. Bu yöntemle sadece temel sınıfta sanal
 olarak bildirilmiş metotların türeyen sınıfta devre dışı bırakılmış olan metotlara erişilebilir.

Sunday, October 14, 2012

Is ve As Operatörleri (c#)


As  Operatörü

as operatörü uygun türler arasındaki dönüşümü sağlar. Kullanımı aşağıdaki biçimdedir.

<referans tipi üretitilecek ifade>   as   <referans türü>

as operatörü kullanımı fazla yaygın değildir. as operatörün ürettiği değer referans türündendir, eğer dönüşüm işlemi
başarızsa null değer üretilir. Örneğin object türünden olan bir nesne string türüne aşağıdaki şekilde dönüştürülür.

Using System;

class Operatorler
{
   static void main()
   {
      object i = "50";
      string s = i as string;
      console.writeline(s);
   }
}


Is Operatörü

is operatörü çalışma zamanında bir nesnesinin türünün operand ile verilen türe uyumlu olup olmadığını kontrol eder.
Kullanımı aşağıdaki gibidir.

<ifade> is <tür>

is operatörü de as operatörü gibi pek fazla kullanılmamaktadır. Ancak yine de dilin olanaklarından haberdar olmak önemlidir.
is operatörünün ürettiği değer true ya da false değeridir. Eğer operandlardaki türler uyumlu ise true, değilse false
değeri üretilir.

<ifade> is <tür> ifadesinin her zaman true ya da her zaman false üretmesi durumunda derleyici hata bir uyarı verecektir.
ancak bu derleme işlemine engel değildir.

Aşağıda ki programı derlediğimizde derleyicinin verdiği uyarının ekran görüntüsü şöyledir:

using Operatorler
{
  static void main()
  {
    int i = 50;
    bool b1 = is int;
    bool b2 = is double;
    bool b3 = is object;
 
   console.writeline(b1);
   console.writeline(b2);
   console.writeline(b3);

  }
}

  Verilen ifade her zaman ('int') türünü sağlar.
  Verilen ifade hiçbir zaman ('double') türünü sağlamaz.
  Verilen ifade her zaman ('object') türünü sağlar.

  Yukaridaki programı çalıştırdığımızda ise aşağıdaki ekran görüntüsünü elde ederiz.
  True
  False
  True