Giriş
Yordamsal programlama dilleri belirli bir sistematik düzende değildi. Bu nedenden dolayı büyük program geliştirme projelerinde çoğu zaman çözümü güç olan zorluklarla karşılaşılmıştır. Bunun üzerine sistematik bir yapıya sahip nesnel programlama dilleri ortaya çıktı. Bunun sayesinde projenin bütünü olan detayların parçalar halinde tasarlanıp kodlanması kolaylaşmıştır. Bu parçalara sınıf(class) adı verilir. Uygulamanın bütünü de bir sistem olduğu için bazı nesnel dillerde programın geneli de bir sınıf olarak kabul edilir. Programın bütünü temel görevler halinde sınıflara ayrılır, tasarlanır ve kodlanır. Daha sonra bu sınıflar kolayca birleştirilerek sistemin tamamı inşa edilir. Bu sayede proje aynı anda birden fazla koldan gelişebilir ve ileriki zamanlarda değişiklikler kolayca yapılır. Sisteme ek bileşenler de ileriki zamanda sınıf olarak kolayca dahil edilebilir. Bir sınıf da birçok sınıfa bölünebilir. Sınıf yapısı ve nesnel programlama dillerine kısaca bahsettik. Şimdi VBScript içerisinde sınıf tanımlama ve sınıfları devralma konularının nasıl yapıldığına değineceğiz. Sınıf yapısı VBScript'e 5.0 sürümü ile birlikte dahil edilmiştir. Elemanlara erişim izinleri ve olay etkileşimli yapısıyla eksiksiz olarak program geliştiricilere sunulmuştur.
Şimdi VBScript içerisinde bir sınıfın tanımlanmasının nasıl yapıldığını göreceğiz;
class cIsim
'durum ifadeleri
end class
Bir sınıf yukarıdaki şekilde tanımlanırken dikkat edilmesi gereken şeyler vardır. Yukarıdaki örnekte cIsim, belirtilmesi zorunlu olan bir ifadedir. Sınıf için isim belirtme kuralları, standart değişken isim kuralları ile aynıdır. İleriki zamanlarda sınıf devralınırken kullanılır. Bloğun içerisinde bulunan durum ifadelerinin tanımlanması zorunlu değildir ancak boş bir sınıf hiçbir amaca hizmet etmiyeceği için boş bir sınıf tanımlamak mantıksızdır. Bu yüzden durum ifadesi tanımlamak gereklidir. Durum ifadeleri yalnızca değişkenler, özellikler, alt programlar veya fonksiyonlardan oluşabilir. Bunun dışındakiler sınıf içerisinde doğrudan yazılamazlar ancak önceki belirtilen durum ifadeleri içerisinde kullanılabilir.
sınıf içerisinde tanımlanabilir durum ifadeleri;
dim durum ifadesi
function durum ifadesi
private durum ifadesi
property get durum ifadesi
property let durum ifadesi
property set durum ifadesi
public durum ifadesi
sub durum ifadesi
Örnek tanımlanmış sınıf içerisinde durum ifadeleri;
class cIsim
dim iDegisken1,iDegisken2
private iDegisken3,iDegisken4
public sDegisken5,sDegisken6
private sub Class_Initialize()
call KatmanYaz()
iDegisken1=Toplam(iDegisken2,iDegisken3)
iDegisken4=ilkNumerikAl
end sub
private sub Class_Terminate()
sDegisken1=empty
sDegisken2=empty
sDegisken3=empty
sDegisken4=empty
sDegisken5=empty
sDegisken6=empty
end sub
private sub KatmanYaz(byval d1)
Response.Write("<div>" & d1 & "</div>")
end sub
public function Toplam(byval d1,byval d2)
d1=CInt(d1)
d2=CInt(d2)
if IsNumeric(d1) and IsNumeric(d2) then
Toplam=d1+d2
else
Toplam=0
end if
end function
public default property get ilkNumerikAl
dim i
for i=1 to 6
if Eval("IsNumeric(sDegisken" & i & ")") then
ilkNumerikAl=Eval("sDegisken" & i)
exit property
end if
next
ilkNumerikAl=0
end property
public property let DegerTuruAl(deger)
if IsEmpty(deger) then
sDegisken6="değer yok"
else
sDegisken6=TypeName(deger)
end if
end property
public property set NesneAl(referans)
if IsObject(referans) then
call referans.AltProgram1()
call referans.AltProgram2()
sDegisken5=referans.Fonksiyon1("diğer nesnemizin fonksiyonu")
set referans=nothing
else
err.Raise(vbError+1,"cIsim","referans değer nesne değil","","")
end if
end property
end class
Sınıf İçerisinde Kullanılabilir Durum İfadeleri
Daha önce sınıf içerisindeki değişkenler, özellikler, alt programlar veya fonksiyonların erişim yetkileri olduğundan yüzeysel olarak bahsetmiştik. Şimdi ise bunları detaylı olarak inceleyelim. Sınıfların aslında genel yapısı ile sadele belli özellikleri haricinde, dış dünyaya karşı kapalı bir kara kutu gibi olmalıdır. Örneğin elektronik bir cihaz olan televizyondan bahsedelim. Son kullanıcı olarak bizim televizyon a erişim yetkilerimiz sadece elektrik fişini prize takmak, kumandasından çeşitli ayarlamaları yaparak izlemek. Tabiki çok meraklı kullanıcı olmadığımızı hesaba katmazsak, son kullanıcı olarak televizyon içerisindeki yapı bizi hiçbir zaman ilgilendirmez. Oysa televizyon içerisinde de birçok detaylı ayarlamaların yapıldığı yerler vardır. İşte bu noktada televizyonu da bir karakutu ve içerisindeki detaylı ayarlamaları da karakutunun esrarlı parçası olarak kabul edebiliriz. Peki biz bu ayarlamalara ulaşsak ne olurdu. Sistem kararsız çalışabilir veya tamamen bozulabilirdi. İşte erişim yetkileri de bu yüzden vardır. Sistemlerdeki en önemli noktalardan birisi de minimal hata ve kararlı çalışabilirlik. Peki biz bu sınıf karakutusunun gizemli elemanlarına ulaşsak ne olurdu. Sistem, yani program anlık çalışma sırasında hata veya arızalara maruz kalabilirdi.
Şimdi ise sınıf içerisinde yetki tanımlamalarının nasıl yapılacağını inceleyelim. Bunun için bir istisna hariç iki durum ifadesi kullanılır;
public durum ifadesi
private durum ifadesi
örnek olarak;
class cIsim
public isim,soyisim
private tarih
end class
bu örnekteki public ile tanımlanan değişkenler hem sınıf dışarısından hemde sınıf içerisinden kullanılırken, private ile tanımlanan ifadeler yalnızca sınıf içerisinden erişim yetkisine sahiptir. Sınıf içerisinde public olarak tanımlanan değişkenler, sınıf dışarısından bir property durum ifadesiymiş gibi erişilirler. Sınıfı devralma ve özelliklerini kullanma konusunda ileride değineceğiz.
Az önce bir istisna olduğundan bahsetmiştik. Bu da dim durum ifadesidir. Sınıf içerisinde dim ile tanımlanan değişkenler sanki public olarak tanımlanmış gibi davranırlar.Ancak üstüne basarak ifade ettiğim şey dim ile public ifadelerinin aynı olmadığıdır. Ne kadar değişken tanımlamada ikisinin de rolü aynı olsa da diğer ifadeler konusunda bu böyle değildir. Dim durum ifadesi yalnızca değişken tanımlamak için, public ifadesi ise hem değişken hemde diğer ifadeleri tanımlamak için kullanılırlar. Bu yüzden bu ifadeyi yetki konusu ile doğrudan ilişkilendirmedim. Public ve private ifadelerinin görevleri diğer ifadeler için de aynı şekildedir. Public ile tanımlanan ifadeler heryerde, private ile tanımlanan ifadeler yalnızca sınıf içerisinde kullanılabilir.
Olaylar
Önceden zihin çorbası yapmamak için bahsetmediğim bir konuya geldik. Sınıf adındaki karakutu kendi içerisinde olaylara bağlı olarak döner. Tabiki bunun böyle olması şart değildir ama amacına uygun olarak kullanılması onu anlamlı hale getirir. Şimdi bunu bir örnekle açıklayacağım. Birçok kişi çocukluğunda bisiklet sahibi olmuştur, olmayanlarda arkadaş hatrına, arkadaşının bisikletine en az bir kez binmiştir. Bisiklet ile yol alabilmek için sürekli pedal çevirmek gerekir değil mi. Peki bayır aşağı son sürat giden bisiklet üzerinde pedal çevirmenin bir manası varmıdır? Yoktur. Program içerisinde bir değişkenin değer alması veya değer göndermesi durumuna göre bir iş yaptırmamız gerekebilir. Bunu yordamsal programlamada yapmaya çalışsaydık, özel yöntemlerin olmadığını farzedersek sonsuz bir döngü kurar ve sürekli bu değişkenlerin durumunu kontrol ederdik. Fakat bu deminki tabirimizde olduğu gibi, bayır aşağıya boş yere pedal çevirmek olurdu.
Sınıf içerisinde sınıfın devralınması ve serbest bırakılması bir olay olarak yorumlanması için tanımlama yapıabilir;
class cIsim
private sub Class_Initialize()
'sınıf devralındığı anda yaptırılması
'istenen durum ifadeleri buraya yazılmalıdır
end sub
private sub Class_Terminate()
'sınıf terk edilmesi anında yaptırılması
'istenen durum ifadeleri buraya yazılmalıdır
end sub
end class
Yukarıdaki ifadeler public olarak tanımlanabilmesine rağmen, sınıfın candamarını oluşturan olaylar çalışma esnasında dışarıdan erişilebilir özellikte olurlar. Bu da hata veya arızalara neden olacağı için public olarak tanımlanması yanlıştır.
Bunun yanında sınıf içerisindeki bir özellikten değer alınması veya özelliğe değer gönderilmesi de olay olarak işlenebilir. Şimdi de bunu örneklendirelim;
class cIsim
public property get Ifade1
'dışarıdan veya içeriden, Ifade1 özelliğinden
'değer istendiği anda buradaki durum ifadeleri işlenir.
Ifade1="değer"
'beklenen konuma değer yukarıdaki gibi gönderilir.
end property
public property let Ifade2(deger)
'dışarıdan veya içeriden, Ifade2 özelliğine
'değer gönderildiği zaman buradaki durum ifadeleri işlenir.
dim pDeger
pDeger=deger
'değer yukarıdaki gibi bir değişkene alınabilir veya
'doğrudan olduğu gibi kullanılabilir.
end property
public property set Ifade3(referans)
'dışarıdan veya içeriden, Ifade3 özelliğine
'referans gönderilidiği zaman buradaki durum ifadeleri işlenir.
dim pReferans
set pReferans=referans
'referans yukarıdaki gibi bir değişkenle ilişkilendirilebilr
'veya doğrudan olduğu gibi kullanılabilir.
end property
end class
Get, let ve set ayrıntısından bahsedelim. Sınıfdaki tanımlanmış özelliklerin hem değer aldığından hemde değer gönderebildiğinden bahsetmiştik. Değişken şeklinde tanımlanmış özelliklerin olay kontrol yetenekleri olmadığı için bu şekilde tanımlamalara ihtiyac duymuyoruz. Fakat olay etkileşimli olduğu zaman olayın kimin tarafından başlatıldığı tespit edilmesi gerekir. Get şeklinde tanımlanan özellik sınıf dışarısına veri gönderilme, let şeklinde tanımlanan özellik sınıf dışından sayısal veya alfasayısal türde sınıf içerisinde veri gönderme, set şeklinde tanımlanan özellik de sınıf dışarısından nesne türünün sınıf içerisinde referans olarak gönderildiği anda gerçekleşir.
Get diğer iki ifadeyle aynı ifade isimleri ile beraber kullanılabilirken let ve set bu şekilde bir arada kullanılamazlar. Bunu da örneklendirelim;
class cIsim
public property get Ifade1
'...
end property
public property let Ifade1(deger)
'...
end property
private property get Ifade2
'...
end property
private property set Ifade2(referans)
'...
end property
end class
Burada 4 tane özellik tanımlaması yapılmasına rağmen, ilk iki ve son iki özellik aynı isimle isimlendirildikleri için ilk ikisi 1. özelliğin, son ikisi ise 2. özelliğin farklı olaylarını işlemek için kullanılırlar. Peki her bir özellik için tek bir olay kontrolü yapılırsa ne olacak. Get için özellik salt-okunur modda, let ve set için ise salt-yazılabilir durumlarda olacaklardır.
Şimdi özelliğin get olayı için daha önce bahsetmediğimiz birşeyden daha bahsedeceğiz. Get olayı için tanımlanması zorunlu olmayan bir ifade de default ifadesidir.
class cIsim
public default property get Ifade1
'...
end property
end class
Bu şekilde tanımlandığında, sınıf devralındıktan sonra sınıfın adı doğrudan bir aktarma ifadesi ile beraber kullanıldığında bu olay gerçekleşecektir. Bunun detaylı kullanımına sınıfı devralma konusunda inceliyeceğiz.
Bu üç ifade çağrılırken argüman da alınabilir. Şimdi bunu örneklendirelim;
class cIsim
public property get Ifade1(arg1,arg2,arg3)
'...
end property
public property let Ifade1(arg1,arg2,arg3,deger)
'...
end property
private property get Ifade2(arg1,arg2,arg3)
'...
end property
private property set Ifade2(arg1,arg2,arg3,referans)
'...
end property
end class
Gönderilen argümanlar yukarıdaki arg isimli değişkenler üzerinde tutulurlar. Daha sonra bunları olaylara göre dilediğiniz gibi işleyebilirsiniz. Argüman kullanılması opsiyoneldir. Zorunlu değildir.
Alt Programlar ve Fonksiyonlar
Alt programlar ile fonksiyonlar arasındaki bariz fark, birisinin değer göndermesi diğerinin de göndermemesidir. Şimdi alt program ve fonksiyon tanımlanmasını görelim;
class cIsim
public sub AltProg(arg1,arg2)
'değer döndürmez
'...
end sub
private function Fonks(arg1,arg2)
Fonks="döndürülen alfasayısal değer"
'değer döndürür
'...
end function
end class
Gönderilen argümanlar yukarıdaki arg isimli değişkenler üzerinde tutulurlar. Daha sonra bunları olaylara göre dilediğiniz gibi işleyebilirsiniz. Argüman kullanılması opsiyoneldir. Zorunlu değildir. Fonksiyon public olarak tanımlandığında opsiyonel olarak default ifadesi de kullanılabilir. Görevi get özelliğindeki ile aynıdır ancak bu ifade class içerisinde yalnızca bir kez tanımlanmalıdır.
Bahsetmediğimiz bir şeyden daha bahsedelim. Bazı durumda alt program veya fonksiyon içerisindeki yordam yarıda kesilip bırakılması gerekebilir. Bunu gerçekleştiren ise exit ibaresidir. Akış bu ibare ile karşılaştığında end ibaresine ulaşmışçasında yordam sona erer. Örneklendirelim;
class cIsim
public sub AltProg(byval arg1,byref arg2)
if not (IsNumeric(arg1) and IsNumeric(arg2)) then
exit sub
end if
end sub
private function Fonks(byref arg1,byval arg2)
if not (IsNumeric(arg1) and IsNumeric(arg2)) then
exit function
end if
end function
end class
Referans ve Değer Arasındaki Fark
ByVal ve ByRef ifadeleri ne işe yarar? ByVal ın açılımı By Value, ByRef in açılımı ise By Reference manasına gelmektedir. ByVal ile sadece başka bir bellek hücresine alınan argüman değerini ifade ederken, ByRef argüman yolu ile gönderilen değişkenin bellek hücresini ifade eder. ByRef yapısı C dilindeki pointer yapısını andırır. ByRef ile argüman şeklinde alınan değişken ve argüman şeklinde gönderilen değişken, aynı bellek adresini işaret eten birer pointer gibi işler.
Basit bir örnekle şekillendirelim. Aşağıdaki örneği test1.vbs adı ile kaydederek deneyebilirsiniz;
'test.vbs
dim deger1
deger1=10
call Wscript.Echo(deger1)
sub TestRef(ByRef ref1)
ref1=ref1+5
end sub
call TestRef(deger1)
call Wscript.Echo(deger1)
call WScript.Quit()
Aynı örneği alt programdaki ByRef tanımlamasını ByVal olarak değiştirerek tekrar deneyin. Sonunda ikisi arasındaki bariz farkı görebileceksiniz.
Bir sonraki yazımızda da sınıfları devralma, kullanma ve serbest bırakma konularını işleyeceğiz...