Showing posts with label polymorphism. Show all posts
Showing posts with label polymorphism. Show all posts
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.
Subscribe to:
Posts (Atom)