YZM 2105 Nesneye Yönelik Programlama Yrd. Doç. Dr. Deniz KILINÇ Celal Bayar Üniversitesi Hasan Ferdi Turgutlu Teknoloji Fakültesi Yazılım Mühendisliği 1
BÖLÜM - 4 Nesneye Yönelik Programlamaya Giriş Bu bölümde; Sınıflardan Nesne Yaratma, Metotlara Nesne Aktarımı, Properties (Özellikler) Yaratma, Auto-Implemented Properties ile ilgili konular anlatılacaktır. 2
Sınıflardan Nesne Yaratma 3
Nesne Yaratma Bir sınıfı tanımlamak tam olarak bir nesne yaratmak anlamına gelmemektedir. Sınıf sadece kendisinden yaratılacak bir nesnenin nasıl bir şey olacağının soyut açıklamasıdır. Oluşturmak istediğiniz bir varlığın tüm özelliklerini önceden belirlediğinizde, nesne yaratmadan önce bir sınıfın, fieldlarını ve metotlarını yaratmalısınız. 4
Nesne Yaratma (devam ) Sınıf tanımlamasını, yeni bir ev yaratmak için evin ayrıntılı bir planı olarak ya da kek yapmak için gerekli olan kek tarifi olarak da düşünebilirsiniz. Sınıflar oluşturulacak olan herhangi bir nesnenin ayrıntılı bir planıdır. 5
Nesne Yaratma (devam ) Bir nesneyi yaratmak iki aşamadan oluşur. İlk olarak bir değişken tanımlar gibi bir tip ve bir tanımlayıcı atamalısınız. Sonrasında nesneyi yaratabilirsiniz. Örneğin; int veri tipinde ornekdeger değişkenini int ornekdeger; şeklinde tanımlayabildiğimiz gibi Isci nesnesini de, Isci benimasistanim; şeklinde yaratabiliriz. Yaratılan nesne uygun bir ada sahip olmalıdır. 6
Nesne Yaratma (devam ) Isci sınıfından benimasistanim adında bir nesne oluşturduğumuzda, derleyiciye benimasistanim adını kullanacağımız bildirilir. Fakat henüz bellekte benimasistanim nesnesinin barındırdığı değerler için bellekte bir yer tutulmamıştır. Gereken bellek yerini «rezerve/allocate» etmek nesneyi new operatörünü kullanarak yaratmamız gereklidir. 7
Nesne Yaratma (devam ) benimasistanim adındaki Isci nesnesini iki aşamada yaratırız. Öncelikle nesne için bir referans tanımlamalı, sonrasında new operatörü ile derleyicinin benimasistanim nesnesi için yeterli alanı tahsis etmesini sağlarız. Isci benimasistanim; benimasistanim = new Isci(); Aynı satırda iki işlemi de tanımlayabiliriz: Isci benimasistanim = new Isci(); 8
Nesne Yaratma (devam ) Bu ifadede Isci: nesnenin tipi benimasistanim: nesnenin adı Eşittir işareti değeri atar, böylece değer benimasistanim nesnesine atanmış olur. new operatörü ise bellekte yeni kullanılmayan bir bölümün benimasistanim için rezerve (ing.: allocate) edilmesini sağlamaktadır. 9
Nesne Yaratma (devam ) Nesnelerin tanımlayıcıları, nesnelerin bellekteki adreslerinin yerlerini gösterirler. Herhangi bir sınıf referans tipi (ing.: reference type) olarak kullanılır. Diğer bir deyişle bellekteki özel bir yeri gösteren bir tip denebilir. int, double ve float gibi veri tipleri, değişkelerin değerlerini tutar; bu veri tiplerinin aksine referans tipleri bellekteki adresleri tutarlar. 10
Nesne Yaratma (devam ) Isci benimasistanim = new Isci(); ifadesindeki new operatöründen sonra gelen Isci() bölümü bir metot gibi gözükmektedir. Aslında bu Isci nesnesinin constructor ı başka bir deyişle kurucu metodudur. Sınıfınız için bir constructor oluşturmadığınızda, C# sizin için adı sınıfın adı ile aynı olan bir tane kurucu metot yaratır. 11
Nesne Yaratma (devam ) Bir nesne yaratıldığında, onun nonstatic üyeleri, nesnenin tanımlayıcısından sonra konulan bir nokta ve kullanılacak olan metodun adı şeklinde erişilir. Örnek: benimasistanim adında bir Isci nesnesi tanımladığınızda, benimasistanim nesnesinin KarsilamaMesaji metodunu şöyle kullanabiliriz: Isci benimasistanim = new Isci(); MessageBox.Show(benimAsistanim.KarsilamaMesaji); 12
Nesne Yaratma (devam ) KarsilamaMesaji() metodu nonstatic bir metot olduğundan dolayı kullanılabilmesi için Isci sınıfından üretilmiş bir nesne gerektirir. Sınıfı kullanan hiçbir program benimasistanim nesnesinin kimlikno değişkenine direk olarak ulaşamaz, bunun yerine bu nesnenin public metotlarını kullanarak değişkenin değerine erişebiliriz 13
Nesne Yaratma (devam ) Tanımladığımız nesnenin public metotları her yerden çağırılabilir ve kullanılabilir. Isci benimasistanim = new Isci(); MessageBox.Show(benimAsistanim.KarsilamaMesaji); Yukarıdaki kod bloğunu çalıştırdığımızda nesne içerisindeki değeri atanmamış fieldların başlangıç değeri 0 olarak atanır. Eğer her Isci nesnesi için farklı bir kimlikno değerinin sağlanmasını isterseniz, bunun için properties yaratmanız gerekmektedir. 14
Metotlara Parametre Olarak Nesne Aktarımı 15
Metotlara Parametre olarak Nesne Aktarımı Bir metoda nesne aktardığımızda aslında o metoda bir referans aktarmış oluruz (call-by-reference). Böylece nesne parametresinde yapılan herhangi bir değişiklik, çağırıldığı metottaki nesneyi de etkiler. 16
Örnek1: IsciBilgileriniGoster() Metoduna Nesne Aktarımı Isci sınıfından, ilkisci ve ikinciisci adında iki nesne oluşturup bu nesneleri IsciBilgileriniGoster metoduna aktarınız. IsciBilgileriniGoster metodunun prototipi şu şekildedir: internal static void IsciBilgileriniGoster(string komut, Isci isc) { MessageBox.Show("" + komut + " için giriş yapıldı!"); MessageBox.Show( isc.karsilamamesaji()); } 17
Metotlara Parametre olarak Nesne Aktarımı (devam ) Nesnelerin aktarıldığı metotlar nesnelerin yaratıldığı sınıfla aynı veya daha kısıtlı bir erişime sahip olmalıdır. public Isci sınıfından türetilmiş isc nesnesinin aktarıldığı IsciBilgileriniGoster metodunun aynı veya daha az erişime açık olan internal erişim belirleyicisine sahip olması buna örnek gösterilebilir. Bu kısıtlama, Isci sınıfının public olmayan üyelerinin korunmasını sağlar. 18
Properties 19
Properties Yaratmak Sıklıkla, bir nesne ile çağırılan metotlar, o nesnenin fieldlarının durumunu değiştirmek için kullanılır. Örneğin: Isci sınıfı içerisinde, işçinin kimlikno bilgisini ayarlayan ya da değiştiren bir metot yazabilirsiniz. İfade şu şekilde olmalıdır: public void kimliknoayarla(int no) { } kimlikno = no; 20
Properties Yaratmak (devam ) Daha sonra Isci sınıfından benimasistanim adında bir nesne yarattığınızda bu metodu aşağıdaki gibi çağırabilirsiniz: benimasistanim.kimliknoayarla(21); Bu teknik farklı dillerde de bu şekilde kullanılabilir fakat C# ta programlarken benzer işlemler için properties ler kullanılır. 21
Properties Yaratmak (devam ) Property, sınıfın bir fieldına erişim sağlayan bir sınıf üyesidir. Propertyler field ların nasıl ayarlanacağını ve erişimin nasıl olacağını tanımlar. Properties, private field ları ile public metotlar arasındaki en iyi özellikleri bir arada barındırır. Public metotlar gibi private verileri dışarıdan müdahalelere karşı korur, Field lar gibi adları basit değişken adlarının kullanıldığı gibi kullanılır. Properties yarattığınızda, kullandığınız sözdizimi daha kolay anlaşılabilir ve doğal olur. 22
Properties Yaratmak (devam ) C# programcıları properties ları smart fields olarak adlandırırlar. Propertyler, sınıfın field ına erişildiğinde işleme alınacak olan ifadeleri barındıran erişimcilere sahiptir. Özellikle propertyler nesnenin fieldının değerini ayarlamaya yarayan set erişimcilerine ve saklanan verilerin değerlerine erişimini sağlayan get erişimcilerini içerirler. 23
Properties Yaratmak (devam ) Bir property, set erişimcisine sahipse yazılabilir, get erişimcisine sahipse okunabilir olmaktadır. Bir property sadece get erişimcisine sahipse bu property sadece okunabilir (ing.: read-only) olur. C# ta get ve set erişimcilerini genellikle getter ve setter olarak adlandırılırlar. 24
Örnek2: Isci Sınıfına Properties Tanımlanması kimlikno üye değişkenine erişimi sağlayan KimlikNo propertysini tanımlayınız. Tanımladığınız KimlikNo propertysini kullanan KarsilamaMesaji() metodunu tanımlayınız. Isci kimlikno: (int) KimlikNo: (int) public string KarsilamaMesaji() 25
Örnek2: Isci Sınıfına Properties Tanımlanması (devam ) 26
Properties Yaratmak (devam ) Property tanımlanmasında değişken tanımlanmasına benzer bir şekilde; erişim belirleyici, veri tipi ve tanımlayıcı(ad) içermektedir. Ayrıca kıvırcık parantezler içerisinde tanımlanan ifadeleri barındıran bir metot içerir. Property ismi kullandığı field in isminin baş harfi büyük hali olarak tanımlanır.(örn.: kimlikno üye değişkeni için KimlikNo propertiesi gibi.) Property tanımlayıcısından sonra, küme parantezi içerisinde erişimciler (get ve set) tanımlanır. 27
Properties Yaratmak (devam ) Propertylerin yazımındaki büyük ve küçük harflere dikkat edilmelidir. KimlikNo property sinde get erişimcisinin içerisinde geriye döndürülen kimlikno olmalıdır. Eğer get erişimcisinin içerisinde property nin kendisini (yani KimlikNo) döndürürseniz property sonsuz kez kendisine erişmeye çalışacaktır. 28
Properties Yaratmak (devam ) Yazılımcılar sınıfın bir metodunun, aynı sınıfın field ınımı yoksa property sinimi kullanması gerektiği hakkında farklı fikirlere sahiptirler. Genel kanı ise get ve set erişimcilerinin iyi bir şekilde tasarlandığında, her yerde (Sınıfların içerisinde bile) kullanılabilir olduğudur. 29
Properties Yaratmak (devam ) Özel koşullarda keyword gibi davranan tanımlayıcılara contextual keywords denir. C# ta 6 adet contextual words bulunur: get, set, value, partial, where, yield 30
Properties Yaratmak (devam ) Erişimciler(get ve set) metot gibi görünebilir fakat metotlardaki gibi tanımlayıcılarının yanında parantez () bulunmaz. set erişimcisi, parametre alan ve bunu değişkene atayan bir metot gibi davranır. Fakat set erişimcisi bir metot değildir ve beraberinde bir parantez ile kullanılmaz. get erişimcisi ise property ile ilişkilendirilmiş field ın değerini geriye döndürür. 31
Properties Yaratmak (devam ) Bir propertynin set ve get erişimcilerinden faydalanırken set ve get anahtar kelimelerini ayrıca kullanmamıza gerek yoktur. İşlem yapacağımız propertye eşittir operatörü = ile değer atadığımızda set bloğu işleme alınmaktadır. Propertiesin adını kullanarak eriştiğimizde ise get bloğu işleme alınır. 32
Properties Yaratmak (devam ) Örneğin, benimustam adındaki Isci sınıfından türetilmiş bir nesne tanımladığımızda, KimlikNo properties inin değerini aşağıdaki gibi atarız: Isci benimustam = new Isci(); benimustam.kimlikno = 113; İkinci ifadede, KimlikNo property sinin değeri 113 olarak ayarlanmış olur. Eşitliğin sağındaki değer property nin set erişimcisine implicit parametre olarak gönderilmiştir. 33
Properties Yaratmak (devam ) 113 değeri set bloğuna aktarılmış ve set erişimcisinde value adını almıştır. Set erişimcisinin içerisinde de value değeri sınıf field ı olan kimlikno değişkenine atanmıştır. 34
Properties Yaratmak (devam ) Propertyler get erişimcisi sayesinde, basit bir değişken gibi kullanılabilmektedir. Örnek: Önceden tanımlanmış olan işçinin kimlik numarası aşağıdaki gibi yazdırılabilir: Fakat benimustam.kimlikno fieldı private erişim belirleyicisine sahip olduğu için erişilemez ve ekrana yazdırılamaz. 35
Properties Yaratmak (devam ) Önceki örneklerde get ve set erişimcileri, field ın bir değerini döndürme veya değeri field a atama dışında bir işlem yapmamaktadır. Eğer kullanılan field private yerine public olarak tanımlansaydı property kullanmamıza gerek kalmazdı. Fakat bu yöntem (Sınıfın fieldlarını private, onlara erişmeyi sağlayan metotları public tanımlanması), nesneye yönelik programlamanın tutarlı olması için genel olarak kullanılmaktadır. 36
Properties Yaratmak (devam ) Veriyi saklı tutmak ve aynı zamanda verinin değerlerinin nasıl ayarlandığını ve kullandığını kontrol edebilmek, Nesneye Yönelik Programlamanın çok önemli bir özelliğidir. Erişimciler, sınıfın bazı fieldlarının değerlerinin nasıl döndürüleceğine veya fieldlara nasıl erişileceğine dair kısıtlamalar koyarak düzenlenebilir. 37
Properties Yaratmak (devam ) Örnek: Kimlik numarasının değer aralığını belirleyen bir set erişimcisi aşağıdaki gibi yazılabilmektedir: set { } if (value < 100) kimlikno = value; else kimlikno = 100; Bu kod bloğunda set erişimcisi Isci sınıfının kimlikno field ının değerinin 100 den daha büyük olamayacağını kesinleştiren bir kısıtlama koyar. 38
Properties Yaratmak (devam ) Eğer kimlikno değişkeninde direkt olarak erişip, değer ataması yapılmasına izin verilseydi, atanan değerin kontrolü yapılamazdı. Tanımlanan sınıf için bir set erişimcisi kullandığınızda, izin verilen verilerin değerleri üzerinde tam kontrolü elde edilmiş olunur. 39
Auto-Implemented Properties 40
Auto-Implemented Propertylerin Kullanımı Bir property içerisinde farklı şekillerde get ve set erişimcileri yaratabileceği gibi, set erişimcisini sadece verilen değeri atamasını ve get işlemcisinin sadece geriye değer döndürmesini isteyebilirsiniz. Erişimcilerin sadece bu standart işlemleri gerçekleştirmeleri istendiğinde autoimplemented propertyler kullanılır. 41
Örnek3: Auto-Implemented Property Yaratma Atanan değeri kimlikno fieldına aktaran ve geriye kimlikno değerini dönen KimlikNo propertysi yaratınız. 42
Örnek3: Auto-Implemented Property Yaratma (Devam...) KimlikNo propertysini yandaki kod bloğunda olduğu gibi, 11 satırda tanımlanmıştır. Fakat bu kodun daha kısaltılmış hali alttaki gibi olabilir. 43
Örnek3: Auto-Implemented Property Yaratma (Devam...) Bazı yazılımcılar bu propertyi tek satırla da yazmaktadır. C#, KimlikNo propertysinin aşağıdaki gibi yazılmasına izin vermektedir: 44
Auto-Implemented Propertylerin Kullanımı (devam ) public int KimlikNo{get; set;} Üstteki formatta oluşturulmuş propertylere autoimplemented property denir. İçerisinde özelleştirme yapmak istediğiniz Propertyler, auto-implemented property olarak yaratılamaz. Ayrıca get ve set erişimcilerinden herhangi birisi kullanılmayacaksa autoimplemented property olarak yaratılamaz. 45
Auto-Implemented Propertylerin Kullanımı (devam ) Sınıfın içerisinde bulunan propertynin kullanacağı fieldlara backing field denir. Autoimplemented property kullandığınızda backing field yaratmaya gerek yoktur. Propertynin kullanacağı field derleyici tarafından yaratılır. Örnekteki KimlikNo property si için kimlikno field ının yaratılmasına gerek yoktur. Derleyici kimlikno field ını otomatik olarak yaratır ve kullanır. 46
Örnek4: Isci Sınıfına Auto-Implemented Property Tanımlanması (int) KimlikNo, (double) Maas, ve (KimlikBilgisi) KimlikBilgileri autoimplemented propertylerine sahip Isci adında bir sınıf yaratınız. Not: KimlikBilgisi sınıfının özellikleri sonraki slaytta açıklanmıştır. Isci KimlikNo: (int) Maas: (double) KimlikBilgileri: (KimlikBilgisi) 47
Örnek4: Isci Sınıfına Auto-Implemented Property Tanımlanması(Devam...) KimlikBilgisi sınıfı, (ulong) TcKimlikNo, (string) Soyad, Ad, BabaAdi, AnneAdi, DogumYeri ve (DateTime) DogumTarihi autoimplemented propertylerine sahiptir. KimlikBilgisi TcKimlikNo: (ulong) Soyad: (string) Ad: (string) BabaAdi: (string) AnneAdi: (string) DogumYeri: (string) DogumTarihi: (DateTime) 48
Örnek4: Isci Sınıfına Auto-Implemented Property Tanımlanması (devam...) 49
Auto-Implemented Propertylerin Kullanımı (devam ) Eğer sadece okunabilir (read-only) auto implemented propertyler yaratmak istiyorsak, set erişimcisini private olarak tanımlamalıyız. Örnek: public int KimlikNo { get; private set; } Böylece KimlikNo property sine değer ataması yapılamaz. Fakat kendi sınıfındaki metotlar değer ataması yapabilirler. 50
Auto-Implemented Propertylerin Kullanımı (devam ) Daha az sıklıkla kullanılan, dışarıdan değeri ayarlanabilen fakat değerine erişilemeyen bir property yaratmak istersek get erişimcisi private olarak tanımlarız Örnek: public int KimlikNo { private get; set; } 51
public ve private Erişim Belirleyicileri Hakkında Daha Fazla 52
public ve private Erişim Belirleyicileri Hakkında Daha Fazla Veriyi olabildiğince saklamak (ing.:information hiding), Nesneye Yönelik Programlamanın temel prensiplerindendir. Bu yöntemde sınıf fieldları private olarak tanımlanır ve iyi bir şekilde tasarlanmış erişimciler üzerinden bu fieldlara ulaşılmaktadır. Fakat bu yöntemin dışında erişim belirleyicilerini farklı olarak kullanmamız gerekebilmektedir. 53
Örnek5: Hali Sınıfının Yaratılması Propertyleri (int) Uzunluk, Genislik, (read-only) Alan, (string) slogan olan ve private void AlanHesapla() metoduna sahip bir Hali sınıfı yaratınız. Hali Uzunluk: (int) Genislik: (int) Alan: [read-only] (int) slogan: (string) private void AlanHesapla() 54
Örnek5: Hali Sınıfının Yaratılması (devam...) 55
public ve private Erişim Belirleyicileri Hakkında Daha Fazla (devam ) Hali sınıfında, Alan propertysi set erişimcisi içermemektedir. Çünkü program dışından alan fieldının ayarlanmasına izin vermek istenmemektedir. Buna rağmen uzunluk veya genişlik fieldlarının değerleri değiştikçe hesaplanmaktadır. 56
public ve private Erişim Belirleyicileri Hakkında Daha Fazla (devam ) Eğer bir field ın değeri her nesne için aynı ise bu field ı hususi olarak public tanımlayabiliriz. Hali sınıfındaki Slogan field ı her Hali nesnesi için aynı değeri taşıyacaktır. Fakat uzunluk, genişlik veya alan gibi diğer field ların değeri her nesne için aynı değildir. Slogan fieldının sabit bir değere sahip olması için bu değişkeni const (sabit) olarak tanımlarız. 57
public ve private Erişim Belirleyicileri Hakkında Daha Fazla (devam ) Bir değişkeni const olarak tanımladığınızda, tanımlayıcısında static belirleyici anahtar kelimesi geçmese bile static olarak tanımlanır. Diğer bir deyişle bu field, bu sınıftan yaratılmış tek bir nesneye değil de, tamamıyla sınıfa aittir. Static bir field yarattığınızda, bu sınıftan ne kadar sayıda nesne türetilirse türetilsin, static field ın bir kopyası sınıfın tümü için saklanır. Bu field a o sınıftan nesne yaratmadan da ulaşılabilir. 58
public ve private Erişim Belirleyicileri Hakkında Daha Fazla (devam ) Hali nesnesi private erişim belirleyicisi ile tanımlı AlanHesapla() metoduna sahiptir. Uzunluk ve Genislik propertylerinin get ve set erişimcilerinin ikisine de sahip olmasına karşın; Alan property si sadece get erişimcisine sahiptir. 59
Yararlanılan Kaynaklar Sefer Algan, HER YÖNÜYLE C#, Pusula Yayıncılık, İstanbul, 2003 Milli Eğitim Bakanlığı, «Nesne Tabanlı Programlama», 2012 Joyce Farrel, An Introduction to Object- Oriented Programming, Cengage Learning, 2011 http://www.algoritmaveprogramlama.com 60
İYİ ÇALIŞMALAR Yrd. Doç. Dr. Deniz KILINÇ deniz.kilinc@cbu.edu.tr 61