PROGRAMLAMA DİLLERİNE GİRİŞ Ders 6: Sınıflar Yrd. Doç. Dr. Altan MESUT Trakya Üniversitesi Bilgisayar Mühendisliği
Nesneye Yönelik Programlama (NYP) Object Oriented Programming (OOP) 1960'lı yılların sonuna doğru yazılımların karmaşıklığı ve boyutları arttıkça gereken bakımın maliyeti (zaman ve çaba olarak) daha da hızlı artmaktaydı. NYP'yi bu soruna karşı bir çözüm haline getiren başlıca özelliği, yazılımda birimselliği (modularity) benimsemesidir. Birimselliğin ana fikri, her bilgisayar programının, etkileşim içerisinde olan birimler (nesneler) kümesinden oluştuğu varsayımıdır. Bu nesnelerin her biri, kendi içerisinde veri işleyebilir ve diğer nesneler ile çift yönlü veri alışverişinde bulunabilir.
Nesneye Yönelik Programlama (NYP) Object Oriented Programming (OOP) NYP ayrıca, bilgi gizleme (information hiding), veri soyutlama (data abstraction), çok şekillilik (polymorphism) ve kalıtım (inheritance) gibi yazılımın bakımını ve aynı yazılım üzerinde birden fazla kişinin çalışmasını kolaylaştıran kavramları da yazılım literatürüne kazandırmıştır. Sağladığı bu avantajlardan dolayı, NYP günümüzde geniş çaplı yazılım projelerinde yaygın olarak kullanılmaktadır.
Neden NYP? Gerçek hayat problemleri sınıf şablonları kullanılarak bilgisayar ortamına daha kolay ve anlaşılabilir bir biçimde aktarılabilir. Sınıflar ile kodlar düzenli bir biçimde saklanarak zaman kaybı yaşanmaz. Nesne yönelimli programlamada herhangi bir projede kullanılmak üzere yaratılan bir sınıf başka projelerde tekrar kullanılabilir.
Sınıf (Class) Nesnelerin özelliklerini, davranışlarını ve başlangıç durumlarını tanımlamak için kullanılan şablonlara sınıf denilir. Örneğin X marka Y model bir otomobil (nesne), her otomobilde olması gereken temel özelliklere (motor, tekerlek, direksiyon, vs.) sahiptir ve o otomobil için tasarlanmış olan bir prototipten (sınıf) yola çıkarak üretilmiştir.
Özellik (Property) ve Yöntem (Method) Nesnelerin özelliklerini saklamak için sınıf içinde tanımlanmış olan değişkenler özellik olarak isimlendirilir. Bir otomobil sınıfının içinde tanımlanan int maks_hız, string renk, gibi özellikler o sınıfa ait her nesnede var olacak, içerdikleri değerler farklı olabilecektir. Nesnelerin davranışlarını belirlemek için kullanılan sınıf içinde tanımlanmış olan fonksiyonlara yöntem adı verilir. Örneğin: gaz pedalına basma bir yöntem ise otomobilin hızlanması geri döndürdüğü değerdir. Yöntemlerin içinde tanımlanan lokal değişkenler özellik değildir.
C++ ve C# C diline nesneye yönelik programlama yaklaşımının ilave edilmesi ile oluşturulan C++ dilinde bu yaklaşımı kullanmak seçimliktir (Hiçbir sınıf içermeyen bir kod C++ derleyicisi ile derlenebilir). Fakat, C# tamamen nesneye yönelik bir dil olduğu için değişkenler ve fonksiyonlar mutlaka bir sınıf içinde tanımlanmalıdır. C dilinde programın başlangıç noktası olan main() fonksiyonu, C# dilinde Program sınıfına ait bir yöntemdir (sınıfın adı değiştirilebilir).
Örnek: Dikdörtgen Sınıfı class Dikdortgen { public int boy, en; public int Cevre() { return boy*2+en*2; } public int Alan() { return boy*en; Özellikler Yöntemler Bir yöntem ya da özelliğe bulunduğu sınıfın dışından da erişilebilmesini istiyorsak public sözcüğü kullanılır
Sınıflar arası iletişim class Program { static void Main(string[] args) Dikdortgen D = new Dikdortgen(); Console.Write("Dikdörtgenin boyu : "); D.boy = Convert.ToInt32(Console.ReadLine()); Console.Write("Dikdörtgenin eni : "); D.en = Convert.ToInt32(Console.ReadLine()); Console.WriteLine("Çevresi = " + D.Cevre()); Console.WriteLine("Alanı = " + D.Alan()); } Dikdortgen sınıfından D adında bir nesne yaratıldı Dikdortgen sınıfının boy ve en özellikleri public olduğu için Program sınıfından bu özelliklere değer atayabiliyoruz. Benzer şekilde Cevre ve Alan fonksiyonları public olmasa idi buradan erişemezdik.
new Eğer bir nesne yaratıldığında aynı sınıftan başka bir nesneye eşitlenirse, iki nesne aslında aynı hafıza bölgesini kullanan eş nesneler olur: Dikdortgen D = new Dikdortgen(); Dikdortgen E = D; new komutu ile hafızadan (RAM) yeni bir yer tahsisi yapıldığını dizileri incelerken de görmüştük. Aslında tanımladığımız her dizi Array sınıfı türünden bir nesnedir. Örneğin Array sınıfına ait Length özelliği ile dizinin eleman sayısını elde edebiliriz. E.boy = D.boy & E.en = D.en
Ek Bilgi ! Bir sınıf tanımı içinde yer alan özelliklere ilk değer atamak mümkündür. Örneğimizdeki boy ve en özelliklerine tanımlandıkları anda değer atansaydı o sınıftan üretilen bir dikdörtgen ilk anda o değerlere sahip olurdu. public (genel) deyimi kullanılmadan tanımlanan yöntem ve özellikler private (özel) kabul edilir. Yani sadece o sınıf içinde kullanılabilir. static olarak belirlenen bir özellik o sınıftan üretilen tüm nesneler için aynıdır (aynı hafıza bölgesini kullanır).
Yapıcı ve Yıkıcı Yöntemler Bir sınıfın içinde sınıf ile aynı isimde bir yöntem yazılırsa o sınıftan bir nesne yaratıldığı anda o yöntem çağrılacaktır. Buna yapıcı yöntem denir. Farklı sayıda veya farklı veri türlerini parametre olarak alan çok sayıda yapıcı yöntem aynı sınıf içinde tanımlanabilir (o sınıfa ait bir nesne yaratılırken hangi parametreler kullanıldıysa, ilgili yapıcı yöntem çağrılacaktır). Sınıf ile aynı isimde olan ve parametre almayan yöntem isminin başında ~ işareti varsa nesne yok edilirken çağrılır. Bunlara da yıkıcı yöntem denir.
Yapıcı fonksiyon her nesne yaratılmasında çağrılır class Oyuncu { static int Toplam; static Oyuncu() Console.WriteLine("Oyun başladı"); } Oyuncu() Toplam++; Console.WriteLine("Toplam oyuncu: " + Toplam); ~Oyuncu() Console.WriteLine("Bir oyuncu ayrıldı..."); Toplam--; static void Main() Oyuncu ahmet = new Oyuncu(); Oyuncu mehmet = new Oyuncu(); Oyuncu osman = new Oyuncu(); Oyuncu ayse = new Oyuncu(); Statik tanımlandığı için her nesneye ait ayrı bir Toplam değişkeni olmayacak, tüm nesneler aynı değişkeni paylaşacak Statik olan yapıcı fonksiyon program başladığında (henüz hiç nesne yaratılmadan) çağrılır Yapıcı fonksiyon her nesne yaratılmasında çağrılır Yıkıcı fonksiyon nesneler yok edilirken (program sonunda) her nesne için ayrı ayrı çağrılır Programı F10 ile çalıştırıp adım adım izlerken: Bazı oyuncuları blok içine aldığınızda, o bloğa gelmeden oyuncunun yaratılmadığını ve o bloğun bitiminde oyuncunun yok edildiğini görebilirsiniz. Ama o anda yıkıcı fonksiyon çağrılmayıp, program biterken çağrılabilir.
Kalıtım Bir sınıfın yöntem ve özelliklerinin tümünü yada birkaçını başka bir sınıfa geçirmek için kalıtım mekanizmasını kullanabiliriz. Örneğin Kare adında bir sınıf oluştururken; class Kare : Dikdortgen şeklinde yazdığımızda, Kare sınıfı Dikdortgen sınıfındaki public veya protected olarak tanımlanmış olan özellik ve yöntemleri miras olarak alır.
class Dikdortgen { public int boy, en; public int Cevre() { return boy*2+en*2; } public int Alan() { return boy*en; class Kare : Dikdortgen { public int kenar; public void Kenar(){ en = kenar; boy = kenar; } class Program static void Main(string[] args) Kare A = new Kare(); A.kenar = 5; A.Kenar(); Console.WriteLine("Karenin Çevresi : " + A.Cevre()); Console.WriteLine("Karenin Alanı : " + A.Alan()); public yerine; protected yazılırsa Kare sınıfı bu değişkenleri kullanabilir ama Program sınıfı kullanamaz, private yazılırsa ikisi de kullanamaz. kenar değişkeninin değeri Kenar() fonksiyonu ile Dikdortgen’den miras alınan en ve boy değişkenlerine atanıyor Cevre ve Alan fonksiyonları Kare sınıfında tanımlı değil, Dikdortgen sınıfından miras alındı