C#’ta Arayüz(Interface), Sınıf(Class) ve Çoklu Kalıtım
Arayüz(Interface), Sınıf(Class) ve Çoklu Kalıtım
Bugünkü makalemizde, arayüzleri incelemeye devam ediceğiz. Arayüzlerin anlatıldığı ilk makalemizde, arayüzleri kullanmanın en büyük nedenlerinden birisinin sınıflara çoklu kalıtım desteği vermesi olduğunu söylemiştik. İşte bu makalemizde, arayüzlerin, sınıflara çoklu kalıtım desteğini nasıl sağladığını çok basit bir şekilde incelemeye çalışacağız. Hiç vakit kaybetmeden, basit bir uygulama üzerinde bunu gösterelim. Bu uygulamamızda, sınıfımıza, tanımlamış olduğumuz iki arayüzü uygulayacağız. Böylece sınıfımız bu iki arayüzü kalıtımsal olarak almış, çoklu kalıtımı uygulamış olucak.
Şekil 1. Programın Çalışmasının Sonucu. Yukarıdaki kodlarda aslında değişik olarak yaptığımız bir şey yok. Sadece oluşturduğumuz arayüzleri bir sınıfa uyguladık ve çoklu kalıtımlılığı gerçekleştirmiş olduk. Ancak bu noktada dikkat etmemiz gereken bir unsur vardır. Eğer arayüzler aynı isimli metodlara sahip olurlarsa ne olur? Bu durumda arayüzlerin uygulandığı sınıfta, ilgili metodu bir kez yazmamız yeterli olucaktır. Söz gelimi, yukarıdaki örneğimizde, Baslat isimli ortak bir metodun arayüzlerin ikisi içinde tanımlanmış olduğunu varsayalım.
Şimdi bu iki arayüzde aynı metod tanımına sahip. Sınıfımızda bu metodları iki kez yazmak anlamsız olucaktır. O nedenle sınıfımıza aşağıdaki gibi tek bir Baslat metodu ekleriz. Sınıf nesnemizi oluşturduğumuzda, Baslat isimli metodu aşağıdaki gibi çalıştırabiliriz.
Fakat bazı durumlarda, arayüzlerdeki metodlar aynı isimlide olsalar, arayüzlerin uygulandığı sınıf içerisinde söz konusu metod, arayüzlerin her biri için ayrı ayrıda yazılmak istenebilir. Böyle bir durumda ise sınıf içerisindeki metod yazımlarında arayüz isimlerini de belirtiriz.Örneğin;
Metodların isimleri başında hangi arayüz için yazıldıklarına dikkat edelim. Diğer önemli bir nokta public belirtecinin kullanılmayışıdır. Public belirtecini kullanmamız durumunda, “The modifier ’public’ is not valid for this item” (public belirleyicisi bu öğe için geçerli değildir ) derleyici hatasını alırız. Çünkü, metodumuzu public olarak tanımlamaya gerek yoktur. Nitekim, bu metodların kullanıldığı sınıflara ait nesnelerden, bu metodları çağırmak istediğimizde doğrudan çağıramadığımızı görürüz. Çünkü derleyici hangi arayüzde tanımlanmış metodun çağırılması gerektiğini bilemez. Bu metodları kullanabilmek için, nesne örneğini ilgili arayüz tiplerine dönüştürmemiz gerekmektedir. Bu dönüştürmenin yapılması ilgili sınıf nesnesinin, arayüz tipinden değişkenlere açık bir şekilde dönüştürülmesi ile oluşur. İşte bu yüzdende bu tip metodlar, tanımlandıkları sınıf içinde public yapılamazlar. Bu açıkça dönüştürme işlemide aşağıdaki örnek satırlarda görüldüğü gibi olur.
İşte şimdi istediğimiz metodu, bu değişken isimleri ile birlikte aşağıdaki örnek satırlarda olduğu gibi çağırabiliriz.
Gördüğünüz gibi arayüzleri yazmak ve sınıflara çoklu kalıtımı amacıyla uygulamak son derece kolay. Böylece geldik bir makalemizin daha sonuna. İlerleyen makalelerimizde arayüzleri incelemeye devam edeceğiz. Hepinize mutlu günler dilerim.
|
Arayüzler’de is ve as Anahtar Sözcüklerinin Kullanımı
Bugünkü makalemizde, arayüzlerde is ve as anahtar kelimelerinin kullanımını inceleyeceğiz. Bir sınıfa arayüz(ler) uyguladığımızda, bu arayüzlerde tanımlanmış metodları çağırmak için çoğunlukla tercih edilen bir teknik vardır. O da, bu sınıfa ait nesne örneğini, çalıştırılacak metodun tanımlandığı arayüz tipine dönüştürmek ve bu şekilde çağırmaktadır. Bu teknik, her şeyden önce, program kodlarının okunabilirliğini ve anlaşılabilirliğini arttırmaktadır. Öyleki, bir isim uzayında yer alan çok sayıda arayüzün ve sınıfın yer aldığı uygulamalarda be tekniği uygulayarak, hangi arayüze ait metodun çalıştırıldığı daha kolay bir şekilde gözlemlenebilmektedir. Diğer yandan bu teknik, aynı metod tanımlamalarına sahip arayüzler için de kullanılır ki bunu arayüzlere çoklu kalıtımın nasıl uygulandığını gösteren bir önceki makalemizde işlemiştik.
Bu teknik ile ilgili olarak, dikkat edilmesi gereken bir noktada vardır. Bir sınıfa ait nesne örneğini, bu sınıfa uygulamadığımız bir arayüze ait herhangibir metodu çalıştırmak için, ilgili arayüz tipine dönüştürdüğümüzde InvalidCastException istisnasını alırız. Bu noktayı daha iyi vurgulayabilmek için aşağıdaki örneğimizi göz önüne alalım. Bu örnekte iki arayüz yer almakta olup, tanımladığımız sınıf, bu arayüzlerden sadece bir tanesini uygulamıştır. Ana sınıfımızda, bu sınıfa ait nesne örneği, uygulanmamış arayüz tipine dönüştürülmüş ve bu arayüzdeki bir metod çağırılmak istenmiştir.
| using System;
namespace Interface3 { public interface IKullanilmayan { void Yaz(); void Bul(); } public interface IKullanilan { void ArayuzAdi(); } public class ASinifi:IKullanilan { public void ArayuzAdi() { Console.WriteLine(“Arayüz adl:IKullanilan”); } } class Class1 { static void Main(string[] args) { ASinifi a=new ASinifi(); IKullanilan Kul=(IKullanilan)a; Kul.ArayuzAdi(); IKullanilmayan anKul=(IKullanilmayan)a; anKul.Yaz(); } } } |
Bu örneği derlediğinizde herhangibi derleyici hatası ile karşılaşmassınız. Ancak çalışma zamanında “System.InvalidCastException: Specified Cast Is Invalid” çalışma zamanı hatasını alırız. İşte bu sorunu is veya as anahtar sözcüklerinin kullanıldığı iki farklı teknikten birisi ile çözebiliriz. Is ve as bu sorunun çözümünde aynı amaca hizmet etmekle beraber aralarında önemli iki fark vardır. Is anahtar kelimesi aşağıdaki formasyonda kullanılır.
| nesne is tip |
Is anahtar kelimesi nesne ile tipi karşılaştırır. Yani belirtilen nesne ile, bir sınıfı veya arayüzü kıyaslarlar. Bu söz dizimi bir if karşılaştırmasında kullanılır ve eğer nesnenin üretildiği sınıf, belirtilen tip’teki arayüzden uygulanmışsa bu koşullu ifade true değerini döndürecektir. Aksi durumda false değerini döndürür. Şimdi bu tekniği yukarıdaki örneğimize uygulayalım. Yapmamız gereken değişiklik Main metodunda yer almaktadır.
| static void Main(string[] args)
{ ASinifi a=new ASinifi(); IKullanilan Kul=(IKullanilan)a; Kul.ArayuzAdi(); if(a is IKullanilmayan) { IKullanilmayan anKul=(IKullanilmayan)a; anKul.Yaz(); } else { Console.WriteLine(“ASinifi, IKullanilmayan arayüzünü uygulamamıştır.”); } } |
Şekil 1: is Anahtar Kelimesinin Kullanımı.
If koşullu ifadesinde, a isimli nesneyi oluşturduğumuz ASinifi sınıfına, IKullanilmayan arayüzünü uygulayıp uyguladığımızı kontrol etmekteyiz. Sonuç false değerini döndürecektir. Nitekim, ASinifi sınıfına, IKullanilmayan arayüzünü uygulamadık.
Is anahtar sözcüğü arayüzler dışında sınıflar içinde kullanabiliriz. Bununla birlikte is anahtar sözcüğü kullanıldığında, program kodu Intermediate Language (IL) (Ortak Dile) çevrildiğinde, yapılan denetlemenin iki kere tekrar edildiğini görürüz. Bu verimliliği düşürücü bir etkendir. İşte is yerine as anahtar sözcüğünü tercih etmemizin nedenlerinden biriside budur. Diğer taraftan is ve as teknikleri, döndürdükleri değerler bakımından da farklılık gösterir. Is anahtar kelimesi, bool tipinde ture veya false değerlerini döndürür. As anahtar kelimesi ise, bir nesneyi , bu nesne sınıfına uygulanmış bir arayüz tipine dönüştürür. Eğer nesne sınıfı, belirtilen arayüzü uygulamamışsa, dönüştürme işlemi yinede yapılır, fakat dönüştürülmenin aktarıldığı değişken null değerine sahip olur. As anahtar kelmesinin formu aşağıdaki gibidir.
| sınıf nesne1=nesne2 as tip |
Burada eğer nesneye belirtilen tipi temsil eden arayüz uygulanmamışsa, nesne null değerini alır. Aksi durumda nesne belirtilen tipe dönüştürülür. İşte is ile as arasındaki ikinci farkta budur. Konuyu daha iyi anlayabilmek için as anahtar kelimesini yukarıdaki örneğimize uygulayalım.
| static void Main(string[] args)
{ ASinifi a=new ASinifi(); IKullanilan Kul=(IKullanilan)a; Kul.ArayuzAdi(); IKullanilmayan anKul=a as IKullanilmayan; if(anKul!=null) { anKul.Yaz(); } else { Console.WriteLine(“ASinifi IKullanilmayan tipine dönüştürülemedi”); } } |
Burada a nesnemiz ASinifi sınıfının örneğidir. As ile bu örneği IKullanilmayan arayüzü tipinden anKul değişkenine aktarmaya çalışıyoruz. İşte bu noktada, ASinifi, IKullanilmayan arayüzünü uygulamadığı için, anKul değişkeni null değerini alıcaktır. Sonra if koşullu ifadesi ile, anKul ’un null olup olmadığı kontrol ediyoruz. Uygulamayı çalıştırdığımızda aşağıdaki sonucu elde ederiz.
Şekil 2: as Anahtar Kelimesinin Kullanımı
Geldik bir makalemizin daha sonuna. Bir sonraki makalemizde görüşmek dileğiyle hepinize mutlu günler dilerim.
Sınıf (Class) Kavamına Giriş
| Bu makalemizde ADONET kavramı içerisinde sınıfları nasıl kullanabileceğimizi incelemeye çalışacak ve sınıf kavramına kısa bir giriş yapıcağız. Nitekim C# dili tam anlamıyla nesne yönelimli bir dildir. Bu dil içerisinde sınıf kavramının önemli bir yeri vardır. Bu kavramı iyi anlamak, her türlü teknikte, sınıfların avantajlarından yararlanmanızı ve kendinize özgü nesnelere sahip olabilmenizi sağlar. Zaten .net teknolojisinde yer alan her nesne, mutlaka sınıflardan türetilmektedir.
Çevremize baktığımız zaman, çok çeşitli canlılar görürüz. Örneğin çiçekler. Dünya üzerinde kaç tür(cins) çiçek olduğunu bileniniz var mı ? Ama biz bir çiçek gördüğümüzde ona çoğunlukla “Çiçek” diye hitap ederiz özellikle adını bilmiyorsak. Sonra ise bu çiçeğin renginden, yapraklarının şeklinden, ait olduğu türden, adından bahsederiz. Çiçek tüm bu çiçekler için temel bir sınıf olarak kabul edilebilir. Dünya üzerindeki tüm çiçekler için ortak nitelikleri vardır. Her çiçeğin bir renginin(renklerinin) olması gibi. İşte nesne yönelimli programlama kavramında bahsedilen ve her şeyin temelini oluşturan sınıf kavramı bu benzetme ile tamamen aynıdır. Çiçek bir sınıf olarak algılanırken, sokakta gördüğümüz her çiçek bu sınıfın ortak özelliklerine sahip birer nesne olarak nitelendirilebilir. Ancak tabiki çiçekler arasında da türler mevcuttur. Bu türler ise, Çiçek temel sınıfından türeyen kendi belirli özellikleri dışında Çiçek sınıfının özelliklerinide kalıtsal olarak alan başka sınıflardır. Bu yaklaşım inheritance (kalıtım) kavramı olarak ele alınır ve nesne yönelimli programlamanın temel üç öğesinden biridir. Kalıtım konusuna ve diğerlerine ilerliyen makalelerimizde değinmeye çalışacağız. Bugün yapacağımız bir sınıfın temel yapı taşlarına kısaca değinmek ve kendimize ait işimize yarayabiliecek bir sınıf tasarlamak. Çiçek sınıfından gerçek C# ortamına geçtiğimizde, her şeyin bir nesne olduğunu görürüz. Ancak her nesne temel olarak Object sınıfından türemektedir. Yani herşeyin üstünde bir sınıf kavramı vardır. Sınıflar, bir takım üyelere sahiptir. Bu üyeler, bu sınıftan örneklendirilen nesneler için farklı değerlere sahip olurlar. Yani bir sınıf varken, bu sınıftan örneklendirilmiş n sayıda nesne oluşturabiliriz. Kaldıki bu nesnelerin her biri, tanımlandığı sınıf için ayrı ayrı özelliklere sahip olabilirler.
Şekil 1. Sınıf (Class) ve Nesne (Object) Kavramı Bir sınıf kendisinden oluşturulacak nesneler için bir takım üyeler içermelidir. Bu üyeler, alanlar (fields), metodlar (methods), yapıcılar (constructor), özellikler (properties), olaylar(events), delegeler (delegates) vb… dır. Alanlar verileri sınıf içerisinde tutmak amacıyla kullanılırlar. Bir takım işlevleri veya fonksiyonellikleri gerçekleştirmek için metodları kullanırız. Çoğunlukla sınıf içinde yer alan alanların veya özelliklerin ilk değerlerin atanması gibi hazırlık işlemlerinde ise yapıcıları kullanırız. Özellikler kapsülleme dediğimiz Encapsulating kavramının bir parçasıdır. Çoğunlukla, sınıf içersinden tanımladığımız alanlara, dışarıdan doğrudan erişilmesini istemeyiz. Bunun yerine bu alanlara erişen özellikleri kullanırız. İşte bu sınıf içindeki verileri dış dünyadan soyutlamaktır yani kapsüllemektir. Bir sınıfın genel hatları ile içereceği üyeleri aşağıdaki şekilde de görebilirsiniz.
Şekil 2 . Bir sınıfın üyeleri. Sınıflar ile ilgili bu kısa bilgilerden sonra dilerseniz sınıf kavramını daha iyi anlamamızı sağlıyacak basit bir örnek geliştirelim. Sınıflar ve üyeleri ile ilgili diğer kavramları kodlar içerisinde yer alan yorum satırlarında açıklamaya devam edeceğiz. Bu örnek çalışmamızda, Sql Suncusuna bağlanırken, bağlantı işlemlerini kolaylaştıracak birtakım üyeler sağlıyan bir sınıf geliştirmeye çalışacağız. Kodları yazdıkça bunu çok daha iyi anlayacaksınız. İşte bu uygulama için geliştirdiğimiz, veri isimli sınıfımızın kodları.
Şimdi ise sınıfımızı kullandığımız örnek uygulama formunu tasarlayalım . Bu uygulamamız aşağıdaki form ve kontrollerinden oluşuyor.
Şekil 3. Form Tasarımımız. Formumuza ait kodlar ise şöyle.
Şimdi uygulamamızı bir çalıştıralım. Değerli okurlarım, ben bu sınıfın geliştirilmesini size bırakıyorum. Umarım sınıf kavramı ile ilgili bilgilerimizi hatırlamış ve yeni ufuklara yelken açmaya hazır hale gelmişsinizdir. Bir sonraki makalemizde sınıflar arasında kalıtım kavramına bakıcak ve böylece nesneye dayalı programlama terminolojisinin en önemli kavramlarından birini incelemeye çalışsacağız. Hepinize mutlu günler dilerim. |
