Yazilim Mutfagi Dersleri ( C#) Ders 5 – Nesneye Dayali Programlamaya Giris

Nesneye Dayali Programlama (Object Oriented Programming)
 

Bu dersimizde Object Oriented Programlamaya basliyoruz. Ilk olarak siniflari (class), nesneleri (object) ve bunlar hakkinda temel bilgileri ögrenecegiz. Ardindan diger derslerimizde yapicilar(constructor), erisim belirleyiciler(Access modifiers), özellikler (properties), method asiri yüklemesi (method overloading) ve static metotlar konularina geçecegiz.

Sinif Kavrami

Bir veri tipini modellemek için kullandigimiz yapilara sinif denir. Bir sinif, kapsüllenmis verileri bu veriler üzerinde islem yapacak metotlari ve bu verilere ait özellikleri içerebilir. Örnegin .Net Framework Class Library içinde bulunan String sinifini inceleyelim. Bu sinif karakterlerden olusan bir dizi barindirir, bu kisma data denir, barindirdigi data üzerinde islemler yapabilecegimiz ToLowerCase(), Trim(),SubString() v.b gibi metotlar içerir. Ayrica barindirdigi dataya ait özellikler içerir. Örn stringin uzunlugunu bulan Lenght özelligi gibi.

C# da bir sinifin tanimlanmasi basitçe asagidaki gibidir.

class YeniClass
{
    //sinif icinde verileri tutacak alanlar,
    //metotlar ve özellikler bu kisma yaziliyor
}

.

Nesneler(Object)

Siniflar bir veri modelidir, nesneler ise bu veri modeline bagli kalarak verileri tutan ve model içerisinde tanimlanmis metotlari ve özellikleri kullanmamizi saglayan modele ait bir referanstir.

YeniClass yeniNesne = new YeniClass()

Yukaridaki kod ile YeniClass sinifi türünde bir yeniNesne ismiyle bir nesne olusturmus olduk. Bu nesne ile sinifin içerdigi tüm modeli kullanabiliriz.

Nesneler referans tipi degiskenler grubuna girerler yani hafizada heap bölümünde olusturulurlar. Referans ve deger tipi degiskenlerine daha önceki derslerimizde deginmistik.

Fields

Fieldler sinif içerisinde veri barindiran alanlardir. ,Fieldler referans veya deger tiplerinden herhangi birisi olabilir, Örn baska bir sinifa referans gösteren nesnelerde bir sinif içerisinde field olarak kullanilabilir.

Bir ögrencinin bilgilerini ve notlarini tutan basit bir sinif yazalim.

class Ogrenci
{
    //sinifa ait fieldler
    string adSoyad;
    int yas;
    int numara;
    int matematikNotu = 0; //ilk deper verilmis..
    int ingilizceNotu;
    int dersOrtalama;
}

Yukaridaki kodda matematikkodu isimli degiskende oldugu gibi siniflara ait fieldlere tanimlama esnasinda deger atamasi yapabilirsiniz. Eger deger atamasi yapmazsaniz degiskenler default degerlerine set edilir. Degisken tiplerine göre default degerleri asagidaki tablodaki gibidir.

Veri Tipi Default Degeri
int 0
long 0
float 0.0
double 0.0
bool FALSE
char \0' (null karakteri
string "" (bos metin)
Object null

Metotlar

Metotlar, verileri kullanarak belirli islemler yapan yapilardir. Metotlar parametre olarak bazi degerler alabildigi gibi gerçeklestirdigi islem sonucunda bazi degerleri de geri döndürürler. Bir metodun yapisi asagidaki gibidir.

<dönüs degis. tipi><metodun ismi>(<parametre tipi> <parametre ismi>,..)
{
    //Metodun gerçeklestirecegi islemler için kod kismi
}

Örnek bir metot;

int ToplamBul(int sayi1, int sayi2)
{
    int toplam = sayi1 + sayi2;
    return toplam;
} 

int MatematikNotunuDondur()
{
    return matematikNotu;
}

Yukaridaki örnekte iki sayiyi parametre olarak alan ve bunlari topladiktan sonra toplamlarini döndüren basit bir metot tanimladik. Metotlar dönüs islemlerini return kelimesi ile yaparlar. Eger tanimladigimiz metot bir dönüs degerine sahip degilse dönüs tipi olarak void yazmaliyiz. Dönüs tipi olarak belirledigimiz degisken tipi ile return ile döndürdügümüz degerin degisken tipi ayni olmak zorundadir.  Dönüs degeri olmayan ve herhangi bir parametre almayan basit bir örnek;

void TarihiYaz()
{
    Console.WriteLine("Suanki Tarih ve Saat : "
+ DateTime.Now.ToString("dd.MM.yyyy HH:mm"));
}

Nesne Olusturulmasi ve Nesneye Deger Atamasi

Bir sinifi referans gösterecek bir nesne olusturmak için new anahtar kelimesi kullanilir.

Ogrenci ogrenci = new Ogrenci();
//Ilk olarak nesneyi tanimlayip daha sonra olusturabilirsiniz..
Ogrenci ogrenci2;
ogrenci2 = new Ogrenci();

Yukaridaki örnekte 2. Yöntem ile tanimlama yaparken Ogrenci ogrenci2; kod parçacigi Ogrenci tipinde bir referans olusturur, fakat bu referans herhangi bir nesne içermez. Bu yüzden bu referansin degeri nulldur. ogrenci2 = new Ogrenci();dedigimizde ise heap de bir nesne olusturulur ve referans degiskenimiz bu alana isaret eder.

Bir Sinifin Üyelerine Erismek

Bir sinifin üyelerine (field, metot veya properties gibi) erismek için sinifa ait nesneden sonra nokta operatörünü kullaniriz.

Ogrenci ogrenci = new Ogrenci();
ogrenci.adSoyad = "Mehmet Sabri KUNT";
ogrenci.yas = 27;
ogrenci.matematikNotu = 89;
ogrenci.ToplamBul(13, 43);
int matnot = ogrenci.MatematikNotunuDondur();

Erisim Belirleyiciler ve Erisilebilirlilik Seviyeleri

Bir sinifa ait üyeler için erisilebilirlilik konusu önemlidir. Peki, Erisilebilirlilik ne demektir? Erisim belirleyiciler kullanarak bir üyenin güvenligini saglamis oluruz. Eger bir üyeye sinifimiz içindeki metotlar disinda herhangi bir erisim yapilmasini istemiyorsak veya projemiz disinda herhangi bir yerden bu üyeye erisim izni vermek istemiyorsak erisim belirleyicileri kullanmak zorundayiz.

Peki, erisimi engellemenin mantigi ne? Bir web servis yazdik ve bu web servisimiz içinde tanimladigimiz bir sinif var. Bu sinifa ait bir üyenin sadece web servis içinde tanimlanmis ve ya web servis projesi içinde tanimlanmis üyeler tarafindan erisilmesini istiyoruz. Web servisi kullanan insanlarin bu üyeye ait degerleri set etmesi veya get etmesi isimize gelmiyorsa, bu üyenin erisilebilirliligini kisitlamamiz gerekir. C# da kullanabilecegimiz toplam 5 farkli erisim seviyesi bulunuyor. Bunlari liste halinde asagida verdim.

Erisim Belirleyici Açiklama
private Erisim seviyesi private olarak ayarlanan üyelere sadece bu üyenin bulundugu sinif içerisinden erisilebilir.
internal Sadece üyenin bulundugu proje içerisinden erisilebilir.
protected Sadece üyenin bulundugu sinif ve bu siniftan türemis alt siniflardan erisilebilir.
protected internal Sadece üyenin bulundugu proje içerisinden ayrica üyenin sinifindan türemis alt siniflar tarafindan erisilebilir.
public public üyelerin erisiminde herhangi bir kisitlama yapilmaz. Istenilen her yerden üyeye erisim açiktir.

Object Oriented programlamada tüm sinif fieldlerinin private yapilmasi ve bu fieldlere erisimin metotlar ve/veya Özellikler(properties) üzerinden saglanmasi tavsiye edilir. Bu sayede fieldlerimize disaridan verilecek degerler kontrol edilebilir. Aksi takdirde disaridan fielde verilecek degerleri kontrol etmemiz imkânsizdir.

Üye tanimlarken eger bir erisim belirleyici kullanmazsak C# default olarak üyemizin erisim seviyesini private yapacaktir.

Namespaceler hariç tüm veri tipleri için erisim belirleyici kullanabilirsiniz. Fakat üst seviye tipler için (sinif, struct, enum) için sadece public ve internal erisim seviyelerini kullanabilirsiniz.

Özellikler(Properties)

Eger siniftaki tüm fieldlerin erisim seviyelerini private yaparsak o zaman bu fieldlere nasil erisebiliriz diye düsünmüssünüzdür. Cevap tabi ki, properties kullanarak. C# properties özelligini destekleyen ilk programlama dilidir. Java ve C++ gibi dillerde private bir fielde deger atamam veya bu fieldin degerini almak için public tanimlanmis metotlar kullanilir. Private bir field tanimlayalim ve bu fielde erisimi metotlar ve properties ler üzerinden nasil yapacagimiza bakalim.

Metot kullanarak:

private int dersNotu;
public void SetDersNotu(int not)
{
    dersNotu = not;
}

public int GetDersNotu()
{
    return dersNotu;
}

Properties kullanarak

private int dersNotu;
public int DersNotu
{
    get { return dersNotu; }
    set { dersNotu = value; }
}

Yukaridaki kodlari incelerseniz properties kullanarak private olan bir fielde erismenin ne kadar kolay oldugunu görürsünüz. Ayrica Visual Studio bir field için properties tanimlamayi otomatiklestiriyor. Bunun için kodunuzdaki fieldi sag tiklayin açilan menüden Refactor->Encapsulate Field menüsünü seçin, yukaridaki get ve set metotlari sizin için otomatik olarak olusturulacaktir. Properties içinde set veya get metotlarinda en az birini tanimlamaniz gerekiyor. Eger fieldinizin sadece readonly olmasini istiyorsaniz set özelligini silerek bunu yapabilirsiniz.

Eger tanimladiginiz field alaninin sadece belirli bir aralikta deger almasi gerekiyorsa, ‘örnegin ders notu 0 ile 100 arasi olmaz zorunda’ set metodu içine bu kontrolü asagidaki gibi ekleyebilirsiniz. Böylece dersNotu isimli fieldinizin alabilecegi degerleri kontrol etmis olursunuz. Bu kontrolü yapabilmek için fieldinize ait erisim seviyesini private yapmali ve asagidaki gibi bir properties kullanmaniz gerekiyor. Sanirim bu kontrol ile bir fielde ait erisim seviyesinin neden private yapilmasi gerektigini anlamissinizdir.

private int dersNotu;
public int DersNotu
{
    get { return dersNotu; }
    set
    {
        if (dersNotu >= 0 && dersNotu <= 100)
            dersNotu = value; 
    }
}

Basit bir örnekle yukarida anlattiklarimiz pekistirelim.

using System;
namespace OOPOrnek
{
   class Program
    {
        static void Main(string[] args)
        {
            Dortgen dortgen = new Dortgen();
            dortgen.KisaKenarUzunlugu = 200;
            dortgen.UzunKenarUzunlugu = 200;
            Console.WriteLine("Kenar Uzunluklari = {0}x{1}",
              dortgen.KisaKenarUzunlugu, dortgen.UzunKenarUzunlugu);
            Console.WriteLine("Dörtgen Tipi : {0}", dortgen.DortgenTipi);
        }
    }
    class Dortgen
    {
        private int kisaKenarUzunlugu;
        private int uzunKenarUzunlugu;
        public int KisaKenarUzunlugu
        {
            get { return kisaKenarUzunlugu; }
            set { kisaKenarUzunlugu = value; }
        }
     
        public int UzunKenarUzunlugu
        {
            get { return uzunKenarUzunlugu; }
            set { uzunKenarUzunlugu = value; }
        }

        public string DortgenTipi
        {
            get
            {
                string tip = "";
                if (kisaKenarUzunlugu == uzunKenarUzunlugu)
                    tip = "Kare";
                else
                    tip = "Dikdörtgen"; 
                return tip;
           }
        }
    }
}

Yukaridaki kodu inceleyecek olursak, basit bir sinif tanimladik. Sinifimiz basit bir dörtgen yapisini barindiriyor. Tabi ki bu sinifi daha detayli hale getirebiliriz. Ilerleyen derslerimizde bu sinifa yeni ilaveler yapacagiz.  Yeni bir console uygulamasi açip yukaridaki kodu Program.cs dosyasinin içine yapistirirsaniz sorunsuz çalisir. Çalistirdiginiz zaman asagidaki çiktiyi elde edeceksiniz.

Kenar Uzunluklari = 200x200
Dörtgen Tipi : Kare
Devam etmek için bir tusa basin . . .

Siniflarin Static Üyeleri

Bir sinida ait üyeye erisebilmek için o sinifa referans eden bir nesne olusturmaniz gerekir. Bu kural static üyeler için geçerli degildir. Yani yukaridaki örnegimizde Dörtgen sinifinda ürettigimiz bir dortgen nesnesini kullanarak kisaKenarUzunlugu üyesine erisebiliriz. Eger sinifimiza ait bir üye varsa ve bu üye bu siniftan türüyen tüm nesnelerde ayi degere sahip olacaksa static metod tanimlamak mantiklidir. Yukaridaki sinifimiza basit bir static üye ekleyelim  ve main fonksiyonu içinden çagiralim.

class Dortgen
    {
        public static int kenarAcisi = 90;
    …
    …
    }


static void Main(string[] args)
{    
     Console.WriteLine(Dortgen.kenarAcisi);
}

Yukarida gördügünz gibi Dortgen sinifinin adini yazdiktan sonra direk olarak static üyemizin ismini yazarak kullandik.  Static üye tanimlarken dikkat etmeniz gereken nokta sudur. Eger bir methodu static tanimladiysaniz, bu metot içinde sinifin üyelerinden static olmayan bir üye kullanamazsiniz. Tersi durumda yani static olmayan bir üye içinde static bir üye kullaniminda ise herhangi bir sorun yoktur.

An object reference is required for the non-static field, method, or property

Yukaridaki gibi bir hata aldiysaniz static bir metor içinde static olmayan bir metot kullanmaya çalisiyorsunuz demektir.

Bir sonraki dersimizde Object Oriented Programlamaya devam edecegiz. Bir sonraki derste görüsmek üzere.

.

16 thoughts on “Yazilim Mutfagi Dersleri ( C#) Ders 5 – Nesneye Dayali Programlamaya Giris

  1. Abi eyvallah ya sagolasin harbiden çok yararli olmus klavyene saglik..

    Iki haftadir kivraniyodum property’i anlayacam diye LOL
  2. 1)Property haline getirerek get set içerisinde kontrol imkanin oluyor get ve set edilen degerleri, su degerde olursa sunu yap falan gibi,

    2)ayrica property yaparsan deger atanirken disaridan erisimi engellemis oluyorsun,field yaptiginda bu sikintiyla karsilasabilirsin. 
  3. Clap yaziyi okudum ve o kadar basarili buldum ki tesekkürü bir borç bildigimden bir mesaj atayim dedim.

    tesekkürler.
  4.  c# da çok yeniyim. property kullanim amacini anlayamiyorum. yani private olan bir fielde erisimin ne kadar kolay oldugundan

    bahsedilmis, private degilde public tanimlarim o zaman. Kullanim amacini anlamis degilim… Rica etsem yardimci olsaniz

  5.  c# da çok yeniyim. property kullanim amacini anlayamiyorum. yani private olan bir fielde erisimin ne kadar kolay oldugundan

    bahsedilmis, private degilde public tanimlarim o zaman. Kullanim amacini anlamis degilim… Rica etsem yardimci olsaniz

  6.  hocam bu konularda  eksilerim vardi yaptiginiz bu aciklamalarla biraz olsun kavramis oldum. elinize emeginize saglik …

  7. Çok akici ve baslangiç için iyi hazirlayici bir anlatim olmus,Elinize emeginize saglik… 

Guests için bir cevap yazın Cevabı iptal et

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir