25 Eylül 2013 Çarşamba

Object Oriented Programming (20) - Inheritance

Object Oriented Programming (20) - Inheritance
Inheritance, basitçe bir class'dan başka class'lar türetmektir. Class'lar arası inheritance uygulamamızın en makul sebebi, "kod maliyetini azaltmak" (yani daha az kod yazmak ) olacaktır. Birbirleriyle benzer classları ayrı ayrı yazmak yerine, ortak üyeleri belirleyerek bir base class oluşturmak ve geri kalanlarını bu base'den türetmek(derived class) çok daha pratik bir çözüm olacaktır. Bu noktada türetilen class’a base class, türeyen class’a ise derived class denir.
NET'de tüm tipler(Class’lar dahil olmak üzere) object'den türer. Burada bahsedilen türeme de, inheritance konusuna işaret etmektedir. Aşağıdaki resimde object tipinde bir değişkenin metodlarını gösterilmektedir.:
 










Herhangi bir int değişkeni veya class içerisinde object tipi içerisindeki tüm method’ları görebiliriz.
 











Örnekte çalışanların tüm ortak property ve methodları Personel class’ı altında toplanmıştır. Daha sonra Personel class’ından Isci ve Memur class’ları türetilmiştir. Ayrıca Memur class’ından Mudur ve Mudur class’ından GenelMudur class’ları türetilmiştir.
namespace OOP4
{
    public class Personel
    {
        private int _id;
        private string _ad;
        private string _soyad;
        private decimal _maas;
        public decimal Maas
        {
            get { return _maas; }
            set { _maas = value; }
        }
       
        public int Id
        {
            get { return _id; }
            set { _id = value; }
        }
        public string Ad
        {
            get { return _ad; }
            set { _ad = value; }
        }
        public string Soyad
        {
            get { return _soyad; }
            set { _soyad = value; }
        }
    }
    public class Isci :Personel
    {
        private decimal _vardiyaUcreti;
        private int _calismaSaati;
        public decimal VardiyaUcreti
        {
            get { return _vardiyaUcreti; }
            set { _vardiyaUcreti = value; }
        }
        public int CalismaSaati
        {
            get { return _calismaSaati; }
            set { _calismaSaati = value; }
        }
    }
    public class Memur : Personel
    {
        private decimal _mesaiUcreti;
        public decimal MesaiUcreti
        {
            get { return _mesaiUcreti; }
            set { _mesaiUcreti = value; }
        }
    }
    public class Mudur : Memur
    {
        private decimal _prim;
        public decimal Prim
        {
            get { return _prim; }
            set { _prim = value; }
        }
    }
    public class GenelMudur : Mudur
    {
        private bool _araba;
        private bool _sporKulubuUyeligi;
        public bool Araba
        {
            get { return _araba; }
            set { _araba = value; }
        }
       
        public bool SporKulubuUyeligi
        {
            get { return _sporKulubuUyeligi; }
            set { _sporKulubuUyeligi = value; }
        }
      
    }
}
 
 
Örneğin Class diyagramı aşağıda gösterilmiştir.




















Microsoft, form üzerindeki bir çok kontrolün(TextBox,Button,Label vs.) ortak property’lerini (BackgroundColor, Text, ForeColor) Control class’ı içerisinde toplar. Daha sonra bu kontrollerin tümünü (Button, Label, TextBox gibi) bu Control classından türetir.

Method Override


Method Override, aynı isme sahip metodların farklı sonuçlar vermesini yani base class içerisinde tanımlanmış method’un derived class içerisinde farklı davranması(yada ezilmesini) sağlar.

Method’ların override yapılabilmesi için, base class içerisinde virtual keyword’ünün kullanılması gerekir. Virtual yapılan metodlar, derived class içerisinde override keyword’ü ile ezilir.

Örnekte base class(Personel) içerisinde virtual olarak belirtilmiş MaasHesapla method’u derived class’lar(Isci, Memur, Musur, GenelMudur) içerisinde override edilerek farklı hesaplama yöntemleriyle hesaplanmıştır.
namespace OOP5
{
    public class Personel
    {
        private int _id;
        private string _ad;
        private string _soyad;
        protected decimal _maas;

        public decimal Maas
        {
            get { return _maas; }
            set { _maas = value; }
        }
       
        public int Id
        {
            get { return _id; }
            set { _id = value; }
        }

        public string Ad
        {
            get { return _ad; }
            set { _ad = value; }
        }

        public string Soyad
        {
            get { return _soyad; }
            set { _soyad = value; }
        }

        public virtual decimal MaasHesapla()
        {
            return _maas * 0.95m;
        }

    }
    public class Isci :Personel
    {
        private decimal _vardiyaUcreti;
        private int _calismaSaati;

        public decimal VardiyaUcreti
        {
            get { return _vardiyaUcreti; }
            set { _vardiyaUcreti = value; }
        }

        public int CalismaSaati
        {
            get { return _calismaSaati; }
            set { _calismaSaati = value; }
        }

        public override decimal MaasHesapla()
        {
              return (_maas * 0.90m) + (_calismaSaati * _vardiyaUcreti) ;
        }
    }

    public class Memur : Personel
    {
        private decimal _mesaiUcreti;

        public decimal MesaiUcreti
        {
            get { return _mesaiUcreti; }
            set { _mesaiUcreti = value; }
        }

        public override decimal MaasHesapla()
        {
            return (_maas * 0.90m) + _mesaiUcreti;
        }
    }

    public class Mudur : Memur
    {
        private decimal _prim;

        public decimal Prim
        {
            get { return _prim; }
            set { _prim = value; }
        }

        public override decimal MaasHesapla()
        {
            return base.MaasHesapla() + _prim;
        }
    }

    public class GenelMudur : Mudur
    {
        private bool _araba;
        private bool _sporKulubuUyeligi;

        public bool Araba
        {
            get { return _araba; }
            set { _araba = value; }
        }
       
        public bool SporKulubuUyeligi
        {
            get { return _sporKulubuUyeligi; }
            set { _sporKulubuUyeligi = value; }
        }

        public override decimal MaasHesapla()
        {
            return base.MaasHesapla() + 5000;
        }
      
    }
}

 
Örnek içerisinde _maas field’ı, protected erişim belirleyicisi ile tanımlanarak, derived class içerisinden erişilebilir olması sağlanmıştır.

Abstract ve Sealead Class


Abstract class’lar, oluşturulması istenen class’ların sadece base class olarak davranması ve üzerinden bir instance oluşturulmamasının istendiği durumlarda kullanılır. C#’da bu fonksiyonaliteyi sağlamak için abstract anahtar sözcüğünü kullanmak yeterlidir.
abstract class Class1
{
....
}

Abstract class’lar içerisindede abstract metodlar olabileceği gibi abstract olmayan (non-abstract) metodlar da olabilir. Abstract metodlar, abstract class içinde implement edilmezler yani içerisinde herhangibir kod bloku barındırmazlar. Kendilerini inherit edecek olan class’lar tarafından yazılmaları gerekmektedir. Aşağıda abstract metod yazım şekli gösterilmektedir.
abstract class abstractClass
{
public abstract void abstractMethod();
}

 
Abstract class’lar içinde mutlaka abstract bir metod yazılması gibi bir zorunluluk yoktur. Yani ihtiyaca göre abstract bir metod sadece non abstract metodlardan da oluşabilir. Aşağıda örnek bir non abstract class yazım şekli gösterilmektedir.
abstract class abstractClass
{public void NonAbstractMethod()
{
Console.WriteLine("NonAbstract Method");
}
}

Fakat genel kullanımı düşünecek olursak abstract class’lar içinde hem abstract hem de non-abstract metodları bir arada sıklıkla kullanılır. Örnek kullanım aşağıda gösterilmektedir.
//Creating an Abstract Class
abstract class absClass
{
//A Non abstract method
public int AddTwoNumbers(int Num1, int Num2)
{
return Num1 + Num2;
}

//An abstract method, to be
//overridden in derived class
public abstract int MultiplyTwoNumbers(int Num1, int Num2);
}

Örnekte MuzikAleti abstract class’ı ve methodunun kullanımı gösterilmektedir.
namespace OOP_15_Abstract
{
    public abstract class Muzikaleti
    {
        public string Marka { get; set; }

        public string Aciklama { get; set; }
        public abstract string Cal();
    }

    public class Gitar : Muzikaleti
    {
        public override string Cal()
        {
           return "Gitar çalıyor";
        }
    }

    public class Bateri : Muzikaleti
    {
        public override string Cal()
        {
            return "Bateri çalıyor";
        }
    }

    public class Flut : Muzikaleti
    {
        public override string Cal()
        {
            return "Flüt çalıyor";
        }
    }
}

Sealed Class’lar kalıtımı alınamayan classlardır. Sealed deyimi ile belirtilmiş class’lar inherit edilemez. Bu class’lardan türetme yapılabilir.

YonetimKuruluBaskani class’ı üzerinden başka bir class kalıtım almayacağı için sealead deyimi ile mühürlenmiştir.
  public sealed class  YonetimKuruluBaskani : GenelMudur
    {
       
    }

Object Oriented Programming (19) - Partial Class

Object Oriented Programming (19) - Partial Class
Fiziksel olarak bir class' ın parçalarının farklı yerlerde bulunması fakat çalışma zamanında tüm parçalarının birleşmesidir. Bir class’ın method, property, field gibi öğeleri partial class ile farklı fiziksel dosyalarda saklanabilir.

Partial Class, büyük ölçekli projelerde, büyük class' larda hata denetimini ve kontrol mekanizmasını daha da arttırmak için yazılır. Karmasa oluşturmamak, nesneyi hemen bulmak için etkili bir yöntemdir.

Örnekte 2 parçadan oluşan Sifre class’ı gösterilmektedir.
public partial class Sifre
    {
        public void EmailleSifreGonder()
        {
        }
        public void SMSileSifreGonder()
        {
        }
    }
    public partial class Sifre
    {
        public string SifreUret()
        {
            return null;
        }
    }
Sifre classın’dan yapılan türetmenin sonucu aşağıdaki gibi olacaktır. Türetme sonucunda tüm öğeler (methodlar) tek liste içerisinde gösterilir.