You are on page 1of 351

JAVA Blm 1: Java'ca Konumaya Balamak ...................................... 1 Blm 2:Alet antamz Dolduralm .............................................. 11 Blm 3: Diziler .........................................................................................

29 Blm 4: Kahvenin Tad Snflarda Sakl .................................... 45 Blm 5: Paketler Kargoda................................................................. 65 Blm 6: Eriimleri Belirlemek (Access Specifiers ) .......... 85 Blm 7: Kaltm ( Inheritance ) ................................................... 101 Blm 8: Final ........................................................................................... 125 Blm 9: Bukalemun ............................................................................ 136 Blm 10: Soyutlama (Abstraction) ........................................... 148 Blm 11: Arayzler (Interfaces) ................................................ 161 Blm 12: Dahili Snflar (Inner Classes)................................ 175 Blm 13: stisnalar (Exceptions) ............................................... 194 Blm 14: 7 Yl Sonra Applet .......................................................... 208 Blm 15: Appletler ile Grsel Tasarm .................................... 217 Blm 16: Appletler ve JBuilder.................................................... 229 Blm 17: Layout ................................................................................... 248 Blm 18: Pencereler........................................................................... 265 Blm 19: JBuilder ile Database Uygulamalar .................... 280 Blm 20: JBuilder ile Database Uygulamalar 2 ........... 299 Blm 21: Java, MySql Balants ................................................ 309 Blm 22: Java ile Grafik izim ..................................................... 318 Blm 23: Servletler ile Dinamik Etkileimli Web Sayfalar ....................................................................................................... 328 Blm 24: lk Bakta JSP (Java Server Pages) .................. 341

Blm 1: Java'ca Konumaya Balamak stanbulda souk bir k gnyd, odamn camndan lapa lapa yaan kar yan seyrediyordum. Her yer bembeyaz olmutu. Evden kmak bile bu tipide delilik olurdu. Ama gelimelerin beni evden kartacan bilemezdim. Elimdeki bir fincan kahveyi yudumlarken, aklma bugne kadar uratm programlama dilleri geldi. niversitede Delphi, sonra C++ ve son olarakta C#. Aralarda ufak apl olsada, Visual Basic ilede ilgilenmitim. Son kahvemden bir yudum daha aldm ve aklma
1

ilgin bir fikir geliverdi. Neden Java ile hi uramamtm. C dilinin kurallarna ve yazm tarzna ok benzeyen gerek anlamda nesne ynelimli, performans yksek, platform bamsz olan bir dil. Aslnda 90l yllarn banda HotJava ile ilk kez tantldn bildiim bu dil zaman ierisinde hide yadsnamayacak bir ilerleme ve gelime gstermiti. Bylesine deerli bir dili grmezden gelmek, bir programc iin iyi olmaz diye dndm. O halde karar verilmiti. Sadece bir kahve molasnda, Java renmeye karar vermitim. Evet ok gzel. Ama nerden ve nasl balamalym. nceki deneyimlerim, bir bilgisayar programlama dilinin nasl ilediini, nasl altn anlamak ve amatr dzeyde uygulamalar gelitirmek iin, merakn balad andan itibaren, en az bir ay sreli sk bir alma gerektirdii ynndeydi. Nitekim konstantrasyon kaybolmadan, mmkn olduu kadar ok kaynaktan e zamanl olarak bir alma yaparak baarya ulamatm hep. yleyse izleyeceim yol belliydi. imdi bana bolca kaynak lazm. Internet zerinde Java ile ilgili saysz kaynak var. Hatta, Kazaa gibi programlar ile, java zerine yazlm pek ok elektronik kitaba ulamakta mmkn. Ancak, doruyu sylemek gerekirse, ekran banda kalp saatlerce bir dkman okumak bence salk asndan pek iyi bir alma sistemi deil. Hereyden nce alma alannn bize huzur veren rahat bir ortam olmas gerekiyor. Geni bir ortam olabilir. Huzuru ise ben ounlukla ece ok ge saatlerde btn mahalle yattnda bulabiliyorum. Alan geni olan bir masa ve bu konuda yazlm kaynaklara ait dkmanlar. Bu dnceler ile yola karak nce Java ile ilgili en gncel kitaplarn neler olduunu internet vastasyla aratrdm. Bu gn itibariyle aadaki tabloda yer alan kitaplar Java zerine yazlm en gncel Trke kaynaklar. Srada bu kaynaklar edinmek var. Bunu ertesi gnde gerekletirebilirim. nk darda bir tipi var. Ama iimdeki renme ve merak hisleri beni bu konuda harekete geiriyor. O gn o tipide dar ktm, Kadkye gittim ve buradaki kitabevlerini, sahaflar gezerek yukardaki kitaplar aradm.
2

Zaten bu kitaplar olduka etkili ve iyi basmlar olduu iin her kitabevinde bulmak mmkn. Hepsi biribirinden deerli yazarlar ve yaynevlerince kartlm. Kitaplarn hepsini temin ettim. Olduka fazla tuttu tabi. Ama renmek iin ilk bata verilecek bu tutar, rendiklerimiz ile yapabileceklerimiz dnldnde gze alnacak bir miktar gibi geldi. Eve dndmde bir buz kalbndan farkszdm. Srt antam Java dilinin arln tayan kitaplar ile bir ka kart daha artm bir halde neredeyse boyumu ksaltmt. Byk bir heyecanla kitaplar alma masamn zerine serdim. Nasl bir hzla ve hevesle baladm bilmiyorum ama hava karardnda, bu dil ile ilgili ilk izlenimlerimi edinmi ve saygn bir gre sahip olmutum. Java daha nceden bahsettiim gibi, 90l yllarda domu bir dil idi. retici firma Sun. Java ile yazlan programlarn ilk ve en ayr edici zellikleri, platform bamsz olmalar. Bunu nasl saladklarn aratrdmda, Virtual Java Machine ( Sanal Java Makinesi) kavram ile karlatm. Bu aslnda gnmz iletim sistemlerinin tmnde bulunuyor. Hatta kullandmz web tarayclarnn sistemimizde olmas bile yeterli. Bu noktada kafam karmt. Bu ara programn amac neydi acaba? ok gemeden cevab buldum. Biz java dili ile bir program yazdmzda bunu Java Derleycisi ile derliyoruz. Derlenmi olan bu dosyalar bytecode ad verilen bir hale geliyor. JVM ise, derlenmi bir java uygulamas balatldnda, bu uygulamay sisteme uygun bir halde yorumluyor ve altryor. Dolaysyla JVM ara programnn ykl olduu her sistemde bu kodlar deitirmeden altrabilme imkanna sahibiz. Sanyorumki bugnlerde mobil telefonlarda java ile yazlm oyunlarn okluunun sebebi bu olsa gerek. lk rendiim bu kavram aslnda bu programlama dilinin gcn ve her programcnn az da olsa gilmesi gerektiini gsterdi bana. O halde komak lazm. Hedefimiz byk. Elbette kuru kuruya bunlar yazmak kolay. Ama basit bir uygulamada gelitirmek ve bir yerden balamak gerekli. ncelikle benim Java programlarn yazmam iin gereken bir takm eyler var bundan eminim. nk bu her zaman byle olmutur. htiyacm olan ilk ve hatta tek eyin, JSDK (Java Software Developer Kit-Java Yazlm Gelitirme Kiti) olduunu reniyorum. Bunu kitaplar ile birlikte gelen cdlerden temin
3

edebiliriz. Ama bence en gncel olan srm takip etmek ve kullanmak her zaman daha iyidir. Kk bir aratrma sonucu aadaki adrese giriyor ve JSDKlarn yaynlanm tm srmlerine ulayorum. Ben burada Offline Kurulum seeneini setim. J2SE iin yaklak olarak 15 megabytelk bir dosya indirdi. Artk indirilen bu dosyay sistemime kurabilirim. Kurulum admlar son derece kolay. Yazlm kitinin kurulmas ile birlikte artk sistemim, java uygulamalarn gelitirmem iin uygun bir yapya sahip oldu. Evet her ey u ana kadar iyi gitti diyebilirim. Peki ama javay nerde hangi editorde yazabilirim. Aratrmam sonucunda her zaman olduu gibi en gl en yetenekli en karizmatik editor ile bu ileri halledebileceim sonucuna vardm. NOTEPAD. Tek yapmam gereken, uygulamay notepad ile yazp, java uzants ile kaydetmek. Daha sonra yazlan bu uygulamlay bytecodelara evirmek iin, javac (Java Compiler-Java Derleyicisi) programn kullanmak. Sonra ise, yazlm olan uygulamay balatmak iin java program ile yazlan bytecodelar altrmak. Aslnda ilk uygulamam yazmak iin sabrszlanyorum. Kaynaklarn hemen hemen hepsi, yeni bir programlama dilini anlatrken ilk yazlan program, Hello World yada Merhaba Dnya olarak adlandrrlar. Bende bu izgide devam edeceim. ok sradan olucak ama bir noktadan balamam gerekiyor. Bu amala kendi bilgisayarmda java rneklerim iin ayr bir klasr atm. Tm rneklerimi burada yazp gelitireceim. imdi, aadaki uygulama kodlarn notepad ile yazp, JavaDunyam.java ismi ile kaydediyorum. public class JavaDunyam { public static void main(String[] args) { System.out.println("Java Dunayasna ilk admm attm galiba..."); } }

imdi bu yazdm kodu java derleyicisi ile derlemem gerekiyor. Hmmm. Peki ama benim java derleyicimin adresi nerede? Bir aramadan sonra kurmu olduum jsdk1.3.1_01 in klasr iinde yer alan bin klasrnde, javac derleyici dosyasn buluyorum. Uygulamay derlemek iin nce bu klasre komut satrndan gittim. Sonu tam anlamyla hsran hem bir hata mesajm var hemde bir program derlemek iin acaip bir yol kattetim.

ncelikle hatay aratrmam gerekiyor. imdi gidip kendime bir kahve almann tam sras. Anlalan bu kahve molamz ok uzun srecek. Aratrmam sonucu kitaplarn vard en nemli ortak nokta u oldu. Java, C dili ve trevleri gibi byk kk harf duyarlkl bir dil. Dolaysyla buradaki hata mesajndan kan sonu snf ad ile java uzantl dosya adnn bire bir ayn olmas. Dikkat ediyorumda da benim dosya adm javadunyam.java ama kullandm snf ad JavaDunyam. Dier taraftan bu kadar hassa bir noktay iyice aratrmam gerektiini dnyorum. Bu kez yle bir komut veriyorum.

Derleyiciye dosya adn snf ad ile ayn ekilde veriyorum Bu kez herhangibir hataya maruz kalmadan uygulamann derlendiini dnyorum. Kontrol etmenin tek yolu var o da klasrn iibe bakmak. Evet java uzantl dosyam, java derleyicim sayesinde, class uzantl bytecode dosyas haline
5

getirilmi. Dikkat ettimde, dosya ad JavaDunyam. Yani snf adm ile birebire ayn. Burdan bir ders aldm, snf adm ile dosya adn birebir yazacam bundan sonra.

Ancak burada houma gitmeyen bir nokta var. Ben her seferinde, bin klasrne mi gideceim? Bu ok sama olur. Kaynak kitaplar, bu konu ile ilgili olarak, bin klasrnnn systemdeki path tanmlamalarna eklenmesi gerektiini sylyorlar. Bunun nasl yapldna baktmda son derece kolay bir ilem olduunu grdm. Xp kullandm iin, windowsun bu versiyonu zerinde, path tanmnn nasl girileceini inceledim. Control Panel den, System penceresine buradada Advanced ksmna buradada Environmet Variables ksmna girdim. Zaten sistemde ykl olan programlar nedeni ile burada bir Path tanmlamas vard. Bunu edit ederek sonuna, jsdkin kurulduu klasrdeki bin dizinini girdim.

Artk ayn java uygulamam bulunduu klasr iinden rahata derleyebiliyorum. Bununla birlikte kaynak kitaplar, birde CLASSPATH ad verilen bir deerin daha girilmesi gerektiini sylyorlar. Bu deeri, sisteme sonradan java uygulamalarn yklediimizde, gerekli snflarn otomatik olarak aranp bulunmas iin yapyormuuz. Doruyu sylemek gerekirse ne demek istediklerini henz tam olarak anlam deilim ama sanyorumki ileride ortaya kacaktr. stedikleri gibi olsun diyerek, bu tanmlamayda ayn ekilde gerekletirdim.

Artk gerekli ayarlamalar yaptma ve uygulamay baarl bir ekilde derlediime gre nasl altna bakmatada yarar var elbette. nk eski deneyimlerim, program kodunun baarl bir ekilde derlenmesi ile, doru bir ekilde almasnn tamamen farkl kavramlar olduun gstermitir hep. Doru ekilde derlenipte mantksal programlama hatalar nedeni ile pek ok istenmeyen sonu doduunu ok iyi biliyorum. Dier yandan yazdm bu bir ka satrlk kod derlendiine gre mantksal olarak bir hata olmayacandan neredeyse eminim. Java ile yazlm uygulamalara ait bytecode dosyalarn altrmak iin, yine bin dizininde bulunan java isimli program kullanyoruz. Ama bu sefet bin klasrne gitmemize gerek yok neyseki. nk path tanmn bu i iin gncelledik. te sonu. Mkemmmel, olaanst bir program demeyi ok isterdim. Ama sadece A harfinin tabanndayz desem yerinde olur herhalde.

Artk program kodlarn incelem zahmetine girebilirim. Kahvemim bitmesinede az kald. lk satrdaki tanmlamamz aslnda bana ok tandk geldi. zellikle C# ile yazlan programlardan. Nitekim Java dilide nesne ynelimli bir dil ve snf kavramnn nemi bu basit kodda bile grnyor. Bu dildede her ey snflar zerine kurulmu durumda. Kaynaklarma baktmda, snflar ile ilgili detayl anlatmlarn yer aldn gryorum. Sanyorum ki, ilerliyen kahve molalarmda bu konulara deinebileceim. Public tanmlamas anladm kadar ile bu snfn baka snflar ierisindende arlabilecei anlamna geliyor ki yle. Daha tandk gelen baka bir satr ise main yordamnn olduu satr. Main yordam java dilindede, programn balang noktas olarak grlyor. Nitekim kodumuzu buraya yazdk. Acaba kim kime benziyor bilemiyorum. Arada pek fark yokmu gibi geliyor ama Microsoft her zamanki gibi benzerlii usta bir pazarlama stratejisi ile ortadan kaldryor. Ltfen M harfinin iki varyasyndada kullanmna dikkat edelim. Java public static void main(String[] args) C# static void Main(string[] args)

Dier yandan System.out.println ifadesi ise " iaretleri arasnda yazlm olan metni, komut penceresine yazdryor. Bu ise C# dilindeki WriteLine ile ayn ileve sahip. Aslnda buradaki kodlar biraz oynamak lazm. Eminimki yeni ufuklar aacaktr. ncelikle main yordamndaki, public kelimesini kaldrmak istiyorum. Bu durumda kodum aadaki gibi grnecek. public class JavaDunyam {

static void main(String[] args) { System.out.println("Java Dunayasna ilk admm attm galiba..."); } } Yazdm uygulamay derlediimde hatasz bir ekilde derlendiini grdm. Class uzantl dosyam oluturulmutu. yleyse her ey yolunda grnyordu. Ama program altrdmda hite yle olmadn grdm.

Main metodunun public olmas gerektii sonucuna hemen varabildim. Aslnda ii biraz daha ileri gtrmek lazm. Neden baka bir snf yazp, JavaDunyam snf iinden bu snfa ait bir nesne rnei yaratmyor ve bu snf iindeki bir metodu armyorum. Ne kadar zor olabilirki. Sonuta java ile program yazarken kendimi C benzeri bir dil ile yazyormuum hissine kaplverdim nedense. te JavaDunyam.java isimli kaynak dosyamn yeni kodlar.

public class JavaDunyam { public static void main(String[] args) { System.out.println("Java Dunayasina ilk adimimi attim galiba..."); } public void Deneme() { System.out.println("JavaDunyam iinden bir ses ver
10

bana..."); } } Bu snf iinde Deneme isimli bir metod tanmladm. Amacm, bu metodu baka bir snf iinden armak. Bu amala Diger isimli baka bir snf Diger.java isimli dosya iinde aadaki gibi tanmladm. public class Diger { public static void main(String[] args) { JavaDunyam jd=new JavaDunyam(); jd.Deneme(); } } Burada yaptm aslnda C# ile yaptm eylerin ayns. JavaDunyam snf iin bir nesne tanmladm. Sonrada nokta notasyonunu kullanarak, Deneme isimli metodu ardm. imdi bu kodlar yeniden derleyip Diger isimli programmz bir altralm. Bakalm herey yolunda gidecek mi?

Daha gzel bir sonu olamazd. Sanyorumki Javay renmeye alrken ok zevk alacam. Bakalm daha neler neler var. Kahvem bitmi. Sanrm bir ara verme vakti. Bir sonraki kahve molasnda bakalm neler olucak. Blm 2:Alet antamz Dolduralm Getiim hafta boyunca, Java ile ilgili kaynaklar ve dkmanlar incelemeye devam ettim. Her programlama dili iin olmassa
11

olmaz gerekli olan bir takm temel bilgileri aratryordum. Bunlar bir programc iin, dilin temel kullanmnda ihtiyac olduu materyallerdir. Genelde her programlama dili iin bunlar gereklidir. Ancak elbette bunlar programlama dilleri arasnda farkllk gsterebilir. Bahsettiim konu, deikenler, koullu ifadeler ve dngler. Bu kahve molasnda bunlar ilemeye alacam. Java programlama dilinde deikenlerin neler olduunu bir tablo halinde hazrladm. Genelde programlama dilllerinde bu tip deiken tipleri hep tablolar halinde sunulur. Deikenleri ska kullandka, bunlarn alt snr, st snr ve alan byklkleri gibi bilgileri zamanla unutabiliriz. ahsen ben hep unuturum. Ancak programlarmz hazrlarken nerede en uygun deiken kullanlr bunu da bilmek isteriz. Ben oldum olas bu tip tablolar ezberleyemem. Zaten ezberleme taraftar deilim. O nedenle bir sr not defterim vardr ve tadm anta genelde ar olur. Java dilinde kullanlan deikenler iinde ayn eyleri hissediyorum. Sanyorum ki bir tablo hazrlayacam ve bunun gzel bir karton basksn yanmda tayacam. Esasen Java dilinde, deikenler, temel veri tipleri olarak anlrlar. Bu anlamda Javada iki veri tipi olduunu syleyebiliriz. Deikenlerin tanmanmas iin kullanlan Temel Veri Tipleri(Primitive) ve nesnelerin tanmlanmas iin kullanlan Referans Tipleri. C# dilindede bu byledir zaten. Temel veri tipinden elde edilen deikenler, bellekte yn ad verilen bir blgede tutulurlar. Oysa referans tiplerin tutulu ekli daha farkl. Referans tipinden bir nesne, sahip olduu ylerin tutulduu bellek blgesindeki alanlarn balang adresine iaret ederki bu tip nesneler ynda tutulurken, sahip olduklar ierik bekte tululur. Java programlama dilinde Temel Veri Trleri aadaki tabloda olduu gibidir. Alan Bykl 8 bit 16 bit 32 bit
12

Veri Tipi byte short int

Kategori

Tamsay Tipleri

long float double char

64 bit 32 bit 64 bit 16 bit Kesirli Say Tipleri Karakter Tipi Mantksal Tip (ture/false)

boolean -

Grld gibi temel veri tipleri bunlar. Aslnda bu tabloda birde alt aralk ve st aralk bilgilerinin olmas gerekiyordu. Ancak bunlar genelde kaynaklarda stsel bilgi olarak gsterilmi. Gerekte, bu veri tiplerinin en st ve en alt snr bilgilerini kk bir program kodu yazarakta renebilirim. te kk programm.

public class Sinirlar { public static void main(String[] args) { System.out.println("Integer veri tipi"); System.out.println("Integer alt snr :"+Integer.MAX_VALUE); System.out.println("Integer ust snr :"+Integer.MIN_VALUE); System.out.println("---"); System.out.println("Double veri tipi"); System.out.println("Double alt snr :"+Double.MAX_VALUE); System.out.println("Double ust snr :"+Double.MIN_VALUE); System.out.println("---"); System.out.println("Float veri tipi"); System.out.println("Float alt snr :"+Float.MAX_VALUE); System.out.println("Float ust snr :"+Float.MIN_VALUE); System.out.println("---");

13

System.out.println("Long veri tipi"); System.out.println("Long alt snr :"+Long.MAX_VALUE); System.out.println("Long ust snr :"+Long.MIN_VALUE); System.out.println("---"); System.out.println("Short veri tipi"); System.out.println("Short alt snr :"+Short.MAX_VALUE); System.out.println("Short ust snr :"+Short.MIN_VALUE); System.out.println("---"); System.out.println("Byte veri tipi"); System.out.println("Byte alt snr :"+Byte.MAX_VALUE); System.out.println("Byte ust snr :"+Byte.MIN_VALUE); System.out.println("---");

} }

imdi yazdm uygulamay Java Derleyicisi ile derliyorum. Hayret, her hangibir hata vermeden derledi. Daha sonrada program altryorum. Sonu gayet gzel oldu. Tam istediim gibi, temel veri trlerine ait alt ve st snr deerlerini elde etmeyi baardm. Bunu yaparken, bu veri tipleri iin Java iinde gelitirilmi hazr snflar kullandm. rnein int veri tipi iin Integer snfn kullandm. Aslnda tm temel veri tipleri iin snflar mevcut. Tek yaptm bu snflarn MAX_VALUE ve MIN_VALUE zelliklerinin deerlerini ekrana yazdrmak oldu. Bu kadar basit.

14

Burada aslnda nemli bir noktada her veri tipi iin bir snfn var olmas. Dolaysyla bir deiken tanmlamasn iki ekilde yapma imkanna sahibim. rnein aadaki kod parasnda, int (integer-tamsay) veri tipinden iki deikenin farkl ekillerde tanmlandn gryoruz. public class DegTan { public static void main(String[] args) { int deger1=45; Integer deger2=new Integer(50); System.out.println("deger1 "+deger1); System.out.println("deger2 "+deger2);

} }

Bu uygulamay altrdmda aadaki sonucu elde ettim.

15

Sonuta iki tane integer tipinde deiken tanmlamtm, ancak bu tanmlamalar arasnda byk farklar olduuna inanyorum. imdi bunu aratrmam gerektiini dnyorum. lk bata gzme arpan, Integer snfn kullanarak, integer tipte veriyi barndran Deger2 isimli bir nesne tanmlamamz. Bu durumda deger2 deerinin bellekte tutulu ekli, deger1den farkl olmaktadr. Dier yandan tm temel veri tiplerinin birer snf mevcuttur ve bu snflar java.lang ad verilen bir pakette bulunmaktadrlar. Kaynaklardan edindiim bilgiye gre, burada ad geen paket kavramnn, C#taki namespace (ad alan) kavram ile ayn olduu sonucuna vardm. Bu bilgiye ulamak benim iin internette biraz zaman harcamak ile gerekleti. Java iin herzaman elimizin altnda bulunmas gereken yardm dokumantasyonu olan Java 2 Platform Std.Ed. Documentation v1.3.1 i http://java.sun.com/j2se/1.3/docs.html adresinden indirdim. Bu dkman yaklak olarak 22 megabytelk bir zip dosyas. Aldnda, html dokumatasyonuna ulaabiliyorsunuz. Burada aradm hemen her konuya ait bilgi mevcut. Ancak baz konularn yannda web pages yazl. Bunlar internetten online olarak baklabilecek yada indirilebilecek adreslere iaret ediyor. te, java.lang paketinin ieriinede bu dokmantasyondan ulatm. Temel veri tiplerine ait snflar kullanarak pek ok fonksiyonu kullanma ansna sahip olduumu grdm. rnein, ilk rneimizde kullandmz MAX_VALUE ve MIN_VALUE zellikleri gibi. Yada integer deeri Stringe dntrmek iin kullanlan toString metodu ve daha pek ok saysz metod yer alyor. Bir dier konuda, Javadaki temel veri trnden deikenler ile, referans trnden nesneler arasndaki temel farkllklar. Burada

16

nemli olan konu, bu iki veri trnnde bellekte farkl ekillerde tutuluyor olmas. Temel veri trnden olan deikenler bellekte kendi isimleri ile stack(yn) ad verilen blgede tutuluyorlar. Referans tipinden olan nesneler ise, bellein heap(bek) ad verilen blgesinde tutuluyor. Tanmlanan referans tipindeki nesne, bekte yer alan verilerine iaret eden ve ynda tutulan bir deiken adna sahip oluyor. Bu kavramlar aslnda karmak gibi grnsede, nesneler arasndaki atamalarda nemli sonular douruyor. Bunu aklamak iin rnekler gelitirmek sanyorumki en dorusu olucaktr. Bu rnekte yapmak istediim, bir snf hazrlamak ve bu snf iinde deikenler tanmlamak. Sonra bu snfa ait bir nesne rnei yaratacak ve onu ayn snftan tretilen baka bir snfa atayacam. Bu ilemlerin gereklemesi halinde bellekteki oluucak hareketleri ise ekille gstermeye alacam. ncelikle rneimi gelitireyim. lk nce nesnelerim iin kullanacam snfm oluturuyorum. public class Sinifim { public int Deger1; public int Deger2; public Sinifim() { Deger1=0; Deger2=0; } public Sinifim(int d1,int d2) { Deger1=d1; Deger2=d2; } public void Yaz() { System.out.println("Deger1 :"+Deger1); System.out.println("Deger2 :"+Deger2); }

17

} Doruyu sylemek gerekirse bu kodlar bize ok ey sylyor. Buradaki kodlar tamamen C#taki bilgimi kullanarak yazdm. rnein snf tanmlamas iinde, iki adet yapc (constructor) metod var. lki Deger1 ve Deger2 isimli deikenlerimize 0 deerlerini atyan parametre almayan ve snflar iin varsaylan olarak kabul edilen yapc metodumuz. Dieri yapc metodumuz ise, bu deikenlere ald parametre deerlerini atyor. Birde Yaz isimli bir metodumuz var. Bu metod ise, snfmzn Deger1 ve Deger2 isimli integer deikenlerini komut satrna yazdryor. Yapc metodlarn kullanm, snflar iindeki yeri gibi kavramlara imdilik gz ucu ile bakm oldum. Bu kavramlar ve daha fazlasn dier kahve molalarmda incelemek istiyorum. Hazr kahve demiken, kahvemi tazelesem iyi olucak sanrm. Gelelim dier snfmza. Bu snfmz ise Sinifim snf trnden nesneler zerinde ilem yapmak iin kullanlyor. public class Program { public static void main(String args[]) { Sinifim sf1=new Sinifim(10,20); System.out.println("Sf1 nesnesi iin"); sf1.Yaz(); Sinifim sf2=new Sinifim(); System.out.println("Sf2 nesnesi iin"); sf2.Yaz(); System.out.println("sf1 nesnesi, Sf2 nesnesine aktarlyor"); sf2=sf1; sf2.Yaz(); } }

18

Bu kodlarla gstermek istediim, referans tipleri arasndaki atamalar sonucu oluan ilikidir. Program iinde, nce sf1 isimli bir nesne rnei oluturuluyor ve bu nesne iindeki Deger1 ve Deger2 integer deikenlerine 10 ile 20 deerleri atanyor. Bu durumda bellein durumunun tasviri aadakine benzer olucaktr.

Daha sonraki admda ise, sf2 isimli baka bir Sinifim nesne rneini oluturuyoruz. Bu kez nesneyi, Sinifim snfnn varsaylan yapc metodu ile oluturuyor ve deikenlerimize 0 deerini atyoruz. Bu halde, bellein durumu u ekilde olucaktr. Bellekte Sinifim, snf trnden iki adet nesne rnei mevcuttur.

Buraya kadar herey normal. Ancak son admda, sf1 , nesnesini sf2 nesnesine atyoruz. te bu durumda olay biraz daha deiik bir hal oluyor. Nitekim, sf1 nesnemiz artk sf2 nesnemize iaret ediyor.

19

imdi rneimizi biraz deitirelim ve Sinifim snfna aadaki DegerAta isimli metodu ve kod satrlarn ekleyelim. public void DegerAta(int d1,int d2) { Deger1=d1; Deger2=d2; }

imdide Program snfna aadaki kod satrlarn ekleyelim. sf1.DegerAta(1,2); sf1.Yaz(); sf2.Yaz(); Bu haldeyken, Program dosyasn altrdmda, her iki nesne rneininde ayn deerleri yazdrdn grrz. Bu u anlama geliyor. Atama ileminden sonra, bekteki ayn blgeyi iaret eden bu iki nesneden birisinin iindeki deerlerin deitirilmesi, dier nesneninde ayn deiiklikleri iaret etmesi anlamna gelmektedir. Sonu aadaki gibi olucaktr.

20

Deikenler aras atamalara gelince. Burada durum referans tiplere gre daha farkl. nk deikenler oluturulduklar isim ile bellekte tutulur. Bu konuyuda bir rnek zerinde incelemek taraftarym. Ksa ve basit bir rnek bize yeterli olucaktr sanrm. public class Program2 { public static void main(String args[]) { int Deger1=50; int Deger2; System.out.println("Deger1 :"+Deger1); System.out.println("Deger2 :"+Deger2); Deger2=Deger1; System.out.println("Deger1 :"+Deger1); System.out.println("Deger2 :"+Deger2); Deger1=48; System.out.println("Deger1 :"+Deger1); System.out.println("Deger2 :"+Deger2); } } Kodu derlediimde hite beklemediim bir hata ile karlatm.
21

Sanyorumki hatann sebebi Deger2 isimli integer veri tipindeki deikene ilk deer atamasn yapmam olmamd. Bu durumda kodun bu satrn aadaki gibi deitirdim ve programn baarl bir ekilde derlendiini grdm. int Deger2=0; imdi uygulamam karlatm. altrdmda aadaki sonular ile

imdi kodu gzelce bir incelemem gerektiini dnyorum. Kahvemden bir yudum aldm ve Javaca dnmeye baladm. lk olarak Deger1 ve Deger2 deikenlerimizi tanmlyor ve bunlara ilk deer olarak srasyla 50 ve 0 deerlerini atyoruz. Bu noktada bellein durumu aadaki tasvirde olduu gibi olucaktr. ki ayr integer tipte deiken bellein yn blgesinde yerlerini almtr.

22

Daha sonraki admda ise, Deger1 deikeninin deeri Deger2ye atanyor. Bu durumda Deger1in sahip olduu 50 deeri, Deger2 deikenine atanm ve bellein grnm aadaki ekilde olmu oluyor.

Son admda ise, Deger1 deikenine 48 deerini atyoruz ve bellekteki Deger1 deikeninin deerinin deimesine neden oluyoruz. Referans tiplerinde olduu gibi, deiken tanmlamalarnda, atamadan sonraki deiiklikler, deikenlerin birbirlerini etkilemesine neden olmamaktadr.

Sanyorumki deiken tipleri ve referans tipleri arasndaki farklar daha iyi anladk. Evet alet antamz doldurmaya devam edelim. Bizim iin gerekli olan dier nemli ve hatta ok nemli unsurlar koullu ifadeler ve dnglerdir. Bu her programlama
23

dili iin byledir. ncelikle karlatrma ifadelerine bir gz atmak istiyorum. Karlatrma ifadelerimiz bana nedense ok tandk geliyor. If ve Switch. Bu ifadelerin kullanmn rnekler ile incelemek taraftarym. ncelikle if koul ifadesini incelemek istiyorum.

public class Kosullar { public static void main(String args[]) { int Not; Not=49; if(Not>50) { System.out.println("Snf getin..."); } else if((Not>45)&&(Not<50)) { System.out.println("Kanaat kullanmalmym bakaym?"); } else { System.out.println("Snfta KALDIN?"); } } } Aslnda her ey ok ak ve ortada. If koullar parantezler iinde yazlr ve karlatrma sonucu true ise hemen izleyen { } kod blou iindeki kodlar altrlr. Eer bu art false ile sonulanr yani gerekli koul salanmaz ise, varsa bir sonraki else kouluna geilir. Burada kullanm olduumuz bir takm karlatrma operatrleride mevcut. Javada kullanlan karlatrma operatrler aadaki tabloda yer almaktadr. Karlatrma Operatr rnek Aklama

24

==

Deger1, Deger2ye eit (Deger1==Deger2) ise true, deilse false dndrr. Deger1 15ten farkl ise true, deilse yani 15e eit ise false dndrr. Deger1 50den kkse true, bykse false dndrr. Deger1 50ye eit veya kk ise true, 50den byk ise false dndrr. Deger1 50den bykse true, kkse false dndrr. Deger1 50ye eit veya bykse true, 50den kkse false dndrr.

!=

(Deger1!=15)

<

(Deger1<50)

<=

(Deger1<=50)

>

(Deger1>50)

>=

(Deger1>=50)

Dier yandan ifadelerimizin birisinde && kullandk. Bu mantksal VE anlamna gelen bir operatrdr. Bu tip mantksal operatrleri, iki veya daha fazla koulun sonularn bir arada
25

deerlendirmek istediimizde kullanrz. Bu rneimizde mantksal operatrmz, belirtilen iki artnda doru olmas artyla izleyen kod bloundaki kodlar altrmaktadr. Javada kullanlan mantksal operatrler aadaki gibidir. Birinci Deer true false false true kinci Deer false true false true && (Ve) false false true true ! (Deili) || ^ (Birinci Deere (Veya) (Yada) Gre ) true true false true true true false false false true

Kaynaklardan mantksal operatrlerden && ve || iin farkl bir kullanm tarz daha olduunu rendim. Buda & ve | operatrleri. Bu iki kullanm tarz arasndaki fark incelediimde olduka ie yarar bir sonula karlatm. && ve || operatrleri, her iki koulunda ileme sokulmasn salar. Ancak bazen ilk koulun true olmas yada false olmas sonucu belirlemek iin yeterlidir. Byle bir durumda her iki kouluda karlatrmaktansa, yani koul ifadesindeki tm kodu altrmaktansa, & ve | operatrlerini kullanarak, sadece soldaki koula baklmasn ve buna gre karar verilmesini salayabiliriz. Gelelim switch koullu ifadesinin kullanmna. Bunuda yine bir rnekle incelemek en gzeli. public class Kosullar { public static void main(String args[]) { int Deger1=3; switch(Deger1) { case 1: { System.out.println("Birinci snf nesnesi olutur."); break;

26

} case 2: { System.out.println("Ikinci snf nesnesi olutur."); break; } case 3: { System.out.println("Ucuncu snf nesnesi olutur."); break; } default: { System.out.println("Ana menuye don."); break; } } } } Aslnda buraya kadar herey ok hzl geliti. Nitekim kullanlan materyaller C dilinden gelmekte ve C# dili iindede aynen kullanlmakta. Bu nedenle bir C# programcs iin Javay renmek veya bir Java programcs iin, C# dilini renmek hzl oluyor diyebilirim. Neyse kahvemizi yudumlamaya devam edelim. Srada dngsel ifadeler var. Bazen bir ilemi birden fazla sayda uygulamak isteyeceimiz durumlar olabilir. Gauss eer bir bilgisayara sahip olsayd inanyorum ki 1den 100e kadar olan saylarn deil 1den 1000e kadar olan saylarn 4nc dereceden kuvvetlerinin toplamn bulan bir uygulama gelitirir ve bizi Gauss formllerini ezberlemekten kurtarrd. Sanyorum programlama dillerini gelitirenler Gaussun ektiklerinden ok, okul yllarnda matematik snavlarndaki Gauss formllerini hatrlayamamaktan ekmiler. Burada, for dngs kullanarak bu ilemin nasl gerekletiini incelemeye alacam. Burada s almak iin, Java iinde yer alan Math snfna ait pow isimli metodu kullandm.

27

public class Dongu { public static void main(String args[]) { double Toplam=0; for(int i=1;i<=1000;i++) { Toplam=Toplam+(Math.pow(i,4)); } System.out.println(Toplam); } } For dngs dnda iki dng eidi daha vardr. Bunlar while dngleridir. ki eit while dngs vardr. Bunlardan birisi, ilk bata koulu kontrol eder ve koul salanyorsa dng iindeki kodlar altrr. Dier eidinde ise, dng iindeki kodlar en az bir kere alr ve koul sonradan kontrol edilir. Her iki dngde koullar saland srece devam eder. rnein yukardaki uygulamamz while dngs kullanarak gerekletirelim. Toplam=0; int i=1; while(i<=1000) { Toplam=Toplam+(Math.pow(i,4)); i++; } System.out.println(Toplam); While dngmzn dier ekli ilede bu dngy yazabiliriz. Toplam=0; int j=1; do
28

Toplam=Toplam+(Math.pow(j,4)); j++;

} while(j<=1000); System.out.println(Toplam); Artk hakiki bir mola vermenin zaman geldi sanrm. Bu kahve molasnda, alet antamz iyice doldurduk. Ancak bu antaya doldurmamz gereken daha ok para olduu kesin. lerleyen kahve molalarnda Javay incelemeye devam edeceiz. Blm 3: Diziler uanda sabahn saat 3 buuu ve yeni hazrladm scak kahvemi yudumlarken, Java ile ilgilenmekten saatn ne kadar ge olduunun farkna bile varamadm. Geen hafta boyunca, Java programlama dilinin temellerini incelemeye devam ettim. Doruyu sylemek gerekirse, skc olan bir ka konu inceledim. Bunlardan birisi dizilerdi. Hemen her programlama dilinde olduu gibi dizilerinde javada skc bir yeri var. Skc olmasn nedeni belkide, veri saklama ile ilgili olarak gnmz teknolojilerinin getirdii veritaban, xml, gelimi koleksiyonlar gibi kavramlarn ok daha fazla tercih ediliyor olmas. Ancak ne olursa olsun, hangi programlama dili olursa olsun ve kavramlar ne kadar skc olursa olsun, bunlar bilmekte, incelemekte fayda var.Bu sabah saatlerindeki kahve molamda, dizilerin Java programlama dili iindeki yerini incelemeye alacam. Bir diziyi belkide en gzel u ekilde tanmlayabiliriz. Dizi, belli bir sayda ve ayn veri trnden deikenlere, ayn isim altnda eriilmesini salayan bir referanstr. Aslnda bu tanm ierisinde ok geni kavramlar var ve aklanmas gerekli. Hereyden nce, dizilerin referans olduklarn sylyor. Java dilindede, C#ta olduu gibi diziler referans tipli verilerdir. Dolaysyla bir dizi, bellein yn (stack) ksmnda tutulurken, dizi elemanlarnn tamam, bek

29

(heap)te yer alr. Yani dizinin ad, bekteki elemanlarn balang adresine iaret eder. Bu dizilerin en nemli unsurlarndan birisidir. Dier yandan, diziler ayn veri trnden elemanlara sahip olmaldr. Bununla birlikte dizilerin eleman saysda oluturulurken belirlenir. Dolaysyla, bir diziyi en batan boyutlandrdmzda, beliltilen sayda eleman aktarabiliriz ve buda dizinin boyutu ile dinamik olarak oynamamz engeller. Doruyu sylemek gerekirse bu kstlamalar belkide C# dilinde koleksiyonlar gelitirilmesine ve daha ok nem kazanmasna neden olmutur. Kimbili belki Java dilindede koleksiyonlar var. imdilik karma kmadlar. O halde ie referans veri tipi olan dizilerin nasl tanmlanacandan balamak gerekiyor. Referans tipli olmas, dizilerin oluturulurken new yaplandrc kullanlarak oluturulmas gerektii sonucunu ortaya kartyor. Nitekim, diziler referans tipli nesnelerdir. Dolaysyla bir snf rnei olmak zorundalar. Ancak dier yandan, bir diziyi olutururken new yaplandrcsn kullanmak zorunda deiliz. Dizi elemanlarna, 0 tabanal bir indis sistemi ile eriebilmekteyiz. Bu anlamda dizilerin, dngler ile karde olmalarn gayet iyi anlayabiliyorum. imdi dizi kavramn incelemek iin basit ama hzl bir rnek gelitirmek dncesindeyim. Kahvemden bir yudum alyorum ve aadaki rnei yazyorum. public class Dizi { public static void main(String[] args) { int dizi1[]=new int[10]; for(int i=0;i<dizi1.length;++i) { dizi1[i]=i*2; System.out.println((i+1)+". eleman="+dizi1[i]); } } } Uygulamay baar ile aadaki sonucu aldm. derledikten sonra altrdmda

30

Kodlarn alma sistematii olduka basit. Diziyi tanmlaka iin new yaplandrcsn kullandk ve dizinin integer veri tipinden 10 elemanl olmasn saladk. Bu noktadan sonra dizimize elemanlar atamak iin bir dng kullandk. Bu dng dizimizin boyutuna kadar hareket eden ve her bir elemana indis deerinin iki katn aktaran bir yapda. Kullandmz length zellii, dizilerin boyutunu elde etmekte kullanlmakta. Buradanda zaten, dizilerin bir Java snfna ait olduu sonucuna varabiliriz. Kodumuzda, dizi elemanlarn okumak iinde ayn dng iindeki dizi1[i] eklindeki yazm kullandk. Dizileri yukardaki rnekte olduu gibi new yaplandrcs ile tanmlayabileceimiz gibi, baka alternatif bir yoluda kullanabiliriz. Benzer bir rnek uygulam aada yer alyor. public class Dizi2 { public static void main(String[] args) { int[] dizi={1,3,5,7,9,11,13,15}; for(int i=0;i<dizi.length;++i) { System.out.println((i+1)+". eleman="+dizi[i]); } } }

31

Burada diziyi tanmlarken elemanlarnda batan atam olduk. Bu ayn zamanda verdiimiz eleman saysna gre dizinin otomatik olarak boyutlandrldnda gstermektedir. Son rneimizin bellekteki yerleim planna gz atarsak aaddaki tasvire benzer bir yapnn olutuunu grrz.

Peki ya bir diziye tanmland veri tipinden baka bir tipte eleman eklemeye kalkarsak ne gibi sonularla karlaabiliriz. Dorusu bunu merak ediyorum. Bu nedenle yukardaki rnekte, integer tipteki dizimize, baka bir veri tipinden eleman eklemeye karar verdim. Bu amala, a karakterini sincizce dizi elemanlar arasna yerletirdim. public class Dizi2 { public static void main(String[] args) { int[] dizi={1,3,5,7,9,11,a,15};

32

for(int i=0;i<dizi.length;++i) { System.out.println((i+1)+". eleman="+dizi[i]); } } } Uygulamay derlediimde her hangibi hata mesaj ile karlamadm. Dier yandan uygulamay altrdmda aadaki hata mesaj beni bekliyordu.

Vouv! Hi beklemediim bir durum. 7nci eleman yani a deerinin karakter karl oluvermiti bir anda. Hmm. Aslnda bu istemediim bir sonu. Ben daha ok bir hata mesaj bekliyordum. Yoksa dizi tanmnda bir tanmlama hatasm yaptm? Denemeye devam etmeye karar verdim. Sabahn ka olursa olsun ben bu hata mesajn bulacaktm. Kodlar aadaki ekilde deitirdim. Aklma ilk gelen integer deilse bir double deeri buraya koymak oldu. Hatta bir tane deil bir ka farkl veri tipinden deerler koymak. public class Dizi2 { public static void main(String[] args) { int[] dizi={1,"Selam naber",5,true,9,11,15.154654,15}; for(int i=0;i<dizi.length;++i) { System.out.println((i+1)+". eleman="+dizi[i]);
33

} }

Sonunda baardm. stediim hata mesajlarn aldm ve dizi tanmna sadk kaldm.

Ancak dizileri kullanrken bama gelebilecek dier hatalarda incelemek istiyorum. ncelikle dizide olmayan bir indis eleman oluturmak istersem veya ona ulamak istersem ne olur? Fazla sze gerek yok hemen kodlar yazmak lazm. Bu kez 5 elemanl bir diziye 6nc eleman eklemeye alacam.

public class Dizi2 { public static void main(String[] args) { int[] dizi={1,2,3,4,5}; for(int i=0;i<dizi.length;++i)
34

System.out.println((i+1)+". eleman="+dizi[i]);

} dizi[6]=7; } } Uygulama yine hatas olarak derlendi. Umarm bu sefer altrdmda istediim hatay alabilirim. Evet. Mkemmel. Hatay elde etmeyi baardm.

Dizileri tanmlarken, ayn veri trnden elemanlar grupladmzdan bahsetmitik. Farkl bir durum daha vardr. Bu da bir diziyi Java dilinin en st snf olan (C# taki gibi) Object trnden tanmlamak ve elemanlar birer nesne olarak belirlemektir. Bu teknikte, dizinin tm elemanlar birer nesnedir. Bu anlamda bellekteki dizilite farkl olmaktadr. yleki, Object trnden bir dizi tanladmzda, dizinin elemanlar bekte tutulurken her bir eleman nesne olduu iin, yine bekteki asl alanlarna referans eden deerleri tarlar. Ancak dizi elemanlarna eritiimizde, bu nesnelerin referans ettikleri bek alanlarndaki verilere ulalr. Hemen bununla ilgili bir rnek yapmakta fayda var. public class DiziObject { public static void main(String[] args) { Integer eleman1=new Integer(456); String eleman2=new String("Ben bir stringim..."); Double eleman3=new Double(45.45687);

35

Boolean eleman4=new Boolean(true); Object[] dizi={eleman1,eleman2,eleman3,eleman4}; for(int i=0;i<dizi.length;++i) { System.out.println((i+1)+". eleman="+dizi[i]); } } } Burada yaptm Object trnden dizim iin, new yaplandrclarn kullanarak srasyla integer, string, double ve boolean veri trlerinden birer nesne yaratmak ve daha sonra bu nesneleri Object trnden diziye aktarmak. Uygulama baarl bir ekilde derlenicektir ve alacaktr.

Bu tekniin bellekteki grnm ise aadaki tasvire benzer ekilde olucaktr.

36

Tabi burada ayn rnei aadaki ekide gelitirmeyide dndm ama bu durumda hata mesajlar ile karlatm. nk aadaki teknii uygulayarak bir Object dizisi oluturmaya altmda, elemanlarn her biri birer deiken olarak algland ve Object dizisine eklenmeye allmak istendi. Ancak Object trnden bir dizi, kendisi gibi nesne elemanlarn kabul edeceinden temel veri trlerinden tanmlanm deilenleri kabul etmedi ve derleyici bir sr hata mesaj verdi. public class DiziObject { public static void main(String[] args) { Object[] dizi={456,"Ben bir stringim",45.45687,true}; for(int i=0;i<dizi.length;++i) { System.out.println((i+1)+". eleman="+dizi[i]); } } }

Ancak burada dikkat etmemiz gereken bir nokta var. O da, String tipteki "Ben bir stringim" iin bir hata mesaj almam olmamz. Bunun nedeni aslnda ok ak. Nitekim String veri tr, bir referans trdr. Dolaysyla new yaplandrcs ile bir

37

String nesnesi yaratabiliriz. Bununla birlikte new yaplandrcsn kullanmadan yukardaki gibi bir string tanmlamakta yine ayn ilevi gerekletirecektir. Sanrm burada bir dip not olarak u iki ifadeninde eit olduklarn syliyebiliriz. String s=new String("Merhabar"); String s="Merhaba";

Gelelim diziler ile ilgili ne tr ilevleri gerekletirebileceimize. Dizilerin Javann bir snf olduu sylemitik. Evet, diziler aslnda, java.util.Arrays snfnn rneklenmi nesneleridir. Geen kahve molamdada internetten indirdiim jsdk dkmanlar iinde bu snf aradm ve saysz pek ok metodunun olduunu grdm. Bunlarn hepsini incelemek iin sanyorumki bir ka hektar kahve tarlamn olmas, bunlar tcek ve ilemden geirerek stlsn, 5 ekerlisini kartp bana sunacak bir fabrikam olmas gerekiyor. Ama sanyorumki bu kahve molasnda en ok iime yarayacaklar incelesem iyi olur. lk gzme arpan ayn isimli metodlardan hemen her veri tr iin ar yklenmi varyasyonlarn oluuydu. rnein sort metodunu ele alalm. Adndanda anlalaca zere bu metod dizi elemanlarn sralyor. Elbette dizinin tipine bal olarak gerekletirilen bir sralama bu. Aadaki rnekte, integer deerlerden oluan bir diziyi u metod prototipini kullanarak sralattm. public static void sort(int[] a) imdide kodlarmz yazalm. import java.util.*; public class DiziSirala { public static void main(String[] args) { int[] dizi={8,6,3,56,12,3,1,0,23,-1,-5}; System.out.println("Siralanmamis Hali"); for(int i=0;i<dizi.length;++i) {
38

} System.out.println(""); System.out.println("Siralanmis Hali"); Arrays.sort(dizi); for(int i=0;i<dizi.length;++i) { System.out.println((i+1)+". eleman="+dizi[i]); } } }

System.out.println((i+1)+". eleman="+dizi[i]);

Burada ncelikle Arrays.sort metodunu kullanarak sralam ilemini yapmak iin, java.util paketini import anahtar kelimesi ile uygulamamza ekledik. Bu C# taki namespacelerin using ifadesi ile eklenmesi ile ayn ey. Integer veri trleri iin tasarlanm bu metodun dier veri trleri iin ar yklenmi versiyonlarda mevcut. Burada metodumuz parametre olarak dizinin adn alyor ve dizinin tipine bakarak uygun olan sort

39

metodunu altryor. Sort metodunun bir dier versiyonuda aada prototipi verilen versiyondur. public static void sort(int[] a,int fromIndex,int toIndex) Bu ar yklenmi versiyona gre, dizinin sadece belirli indisler arasndaki elemanlarnn sralanmasn salam oluyoruz.Bunu yukardaki rneimize uygularsak; import java.util.*; public class DiziSirala { public static void main(String[] args) { int[] dizi={8,6,3,56,12,3,1,0,23,-1,-5}; System.out.println("Siralanmamis Hali"); for(int i=0;i<dizi.length;++i) { System.out.println((i+1)+". eleman="+dizi[i]); } System.out.println(""); System.out.println("Siralanmis Hali"); Arrays.sort(dizi,5,10); for(int i=0;i<dizi.length;++i) { System.out.println((i+1)+". eleman="+dizi[i]); } } }

40

Bir dier ilgin metod ise BinarySearch metodu. Sort metodunda olduu gibi bu metodda dier tm veri trleri iin ar yklemi. Prototipi aadaki gibi olan bu metod, dizi iindeki bir elemann var olup olmadna bakyor ve buna gre bir sonu dndryor. public static int binarySearch(int[] a,int key) imdi bu metod ile ilgili bir deneme yapmann tam sras. import java.util.*; public class DiziBul { public static void main(String[] args) { int[] dizi={8,6,3,56,12,3,1,0,23,-1,-5}; for(int i=0;i<dizi.length;++i) { System.out.println((i+1)+". eleman="+dizi[i]); } System.out.println(""); int sonuc=Arrays.binarySearch(dizi,56); System.out.println("Arama sonucu "+sonuc);

41

lk sonular hite i ac olmad benim iin. Hereyden nce aadaki gibi anlamsz bir sonu elde ettim.

Dkmantasyonu yeniden incelediimde hereyin sebebi anlalyordu. BinarySearch metodunu kullanabilmem iin, dizinin mutlaka sralanm olmas gerekiyor. Bu nedenle koda, sort metodunuda ekledim. Bu durumda, dizimizin sralanm hali zerinden arama ilemi baarl bir ekilde gerekletirilmi oldu. BinarySearch metodunun altrlmas sonucu dnen deer, aradmz elemann dizi iindeki indis numarasdr. import java.util.*; public class DiziBul { public static void main(String[] args) { int[] dizi={8,6,3,56,12,3,1,0,23,-1,-5}; for(int i=0;i<dizi.length;++i) { System.out.println((i+1)+". eleman="+dizi[i]); } System.out.println(""); Arrays.sort(dizi);

42

int sonuc=Arrays.binarySearch(dizi,56); System.out.println("Arama sonucu "+sonuc+".eleman"+dizi[sonuc]); } }

imdi daha deiik bir durumu inceleyelim. Eer dizi iinde olmayan bir eleman ararsak binarySearch metodu nasl bir sonu dndrecektir. Bu amala aadaki kodu hazrladm. rnek iinde, iki adet negatif ve iki adet pozitif tamsayy dizi ierisinde arattm. Bu elemanlarn hibirisin dizinin bir eleman deil. Sonulara baktmda dizide olmayan pozifit elemanlar iin -12 deerini, dizide olmayan negatif elemanlar iin ise -1 deerini elde ettim. Pozifit ve negatif elemanlar iin binarySearch metodunun dndrd deerler farkl olmasna ramen ikise negatiftir. Dolaysyla negatif olmalar dizinin eleman olmadklarn gstermektedir. import java.util.*; public class DiziBul { public static void main(String[] args) { int[] dizi={8,6,3,56,12,3,1,0,23,-1,-5}; for(int i=0;i<dizi.length;++i) { System.out.println((i+1)+". eleman="+dizi[i]);

43

} }

} System.out.println(""); Arrays.sort(dizi); int sonuc1=Arrays.binarySearch(dizi,156); System.out.println("Arama sonucu "+sonuc1); int sonuc2=Arrays.binarySearch(dizi,-8); System.out.println("Arama sonucu "+sonuc2); int sonuc3=Arrays.binarySearch(dizi,1000); System.out.println("Arama sonucu "+sonuc3); int sonuc4=Arrays.binarySearch(dizi,-4568); System.out.println("Arama sonucu "+sonuc4);

Demekki binarySearch metodunu bir if koulu ile kullanarak aranan elemann dizi ierisinde olup olmadn belirleyebiliriz. import java.util.*; public class DiziBul { public static void main(String[] args) { int[] dizi={8,6,3,56,12,3,1,0,23,-1,-5}; for(int i=0;i<dizi.length;++i) {

44

} System.out.println(""); Arrays.sort(dizi); int sonuc1=Arrays.binarySearch(dizi,156); if(sonuc1<0) { System.out.println("BULUNAMADI"); } else { System.out.println("BULUNDU"); } } }

System.out.println((i+1)+". eleman="+dizi[i]);

Arrays snf ile ilgili daha pek ok metod vard ve bunlarda incelemek istiyordum. Ama hava aydnlanmaya ve imeyi unuttuum kahvemde ice-cafe olmaya balamt. Sanrm ara vermek iin en uygun zaman. Biraz dinlenmeyi hakkettik. lerleyen kahve molalarnda kahvemi imeyi unutmayacam. Blm 4: Kahvenin Tad Snflarda Sakl Pazar sabahlar ne yaparsnz? Peki bir bilgisayar programcs olsanz ne yaparsnz? Muhtemelen, cumartesi gecesinin sabaha kadar sren almalarndan banz kaldramadnz iin, btn gn uyumak isteyebilirsiniz. Ben ounlukla ve dzenli olarak, stanbul Bostanc sahilinde ok erken saatlerde yry
45

yaparm. Sabah 6 ile 7 aras inanlmaz bir huzur bulurum burada. Bir yandan denizden gelen tertemiz iyotlu hava, dier yandan sessizlik, mart seslerinin ahengi ve gz kamatrc gzellii ile stanbul boaznn Marmara denizi ile kucaklamas. Matematiki olmamn bana verdii kazanmlardan birisi, etrafta olup bitenleri son derece felsefik inceleyebilme yetenei. Sizde bilirsiniz ki tarihin en nl matematikileri mantk, sosyoloji, felsefe, psikoloji gibi bilimlerle hep yakndan ilgilenmilerdir. Onlardan birisi olmay ok isterdim gerekten. Hereyden nce bir programc pek ok zorlukla, hayatta karlatndan ok, programlarn yazarken karlar. O nedenle, salkl ve ruhsal adan huzurlu bir beden, onun bu zorluklar amasnda en byk yardmcdr. Ben bu yryleri ounlukla kafam boaltmak, kendi dnyamda huzur bulmak ve gzmden kaan ayrntlar daha salkl inceleyebilmek amacyla yaparm. te bu sabahta o amala yaplan bir yryteyim. Admlarm attka, cierlerime dolan nefis iyotlu deniz havas daha salkl dnmemide salyor. Etrafma baktmda, her trden nesneyi daha berrak sezinleyebiliyorum. Nesne! O o! Bu laf bana kim syletti? Nesne...Nesne...Gerekten de yle bir durdum ve etrafma bakndm. Her yerim , ben de dahil olmak zere nesnelerden olumaktayd. Evrenin sahip olduu gizemi ve mkemmellii kimse inkar etmez. amz boyunca ve gelecektede pek ok teknolojik, endstriyel, matematik yaklama ilham kayna olmu sistematikler ierir. Bu dnceler ile tekrar yrmeye baladmda, nasl olduysa bir anda kendimi bilgisayar dillerinin geliimini dnrken buluverdim. Basic, pascal, C, Fortran vesaire... Sonra tekrar durdum. Aklma C++,Java,C# gelivermiti birden bire. Hepside nesneler ile uraan, nesneler zerine kurulu yaplara sahipti. Hepside Nesneye Dayal Programlama dillerindendi. Nesne kavramn, gnmz modern programlama dillerine kim yerletirmi ise eminimki benim gibi bir yry srasnda bunu yapmtr diye dnyordum. Bir anda kendimi Yazlm Mimarlar gibi dnrken, ayam yere srtp tepe taklak tabir yerinde ise iki seksen yere uzandm. Allahn tokat yoktur derler. Neyseki kendime gelmitim. O adamlarn trna bile
46

olmak byk bir onur olurdu sanrm. Evet sonu itibariyle sabahlar bu kadar erken yrmemin nedeni buydu. Tkezleyip dtmde etrafta kimsenin olmay...Sonu itibariyle geriye dnp baktmda, hem programlama dillerinin nesneye dayal hale gelmesi ile, yaammzn ekosistemini rnek alarak ne kadar byk stnlkler saladn dnyor, bir yandanda ne kadar uzaa yrmm imdi nasl geriye dnecem diye veryansn ediyordum. Aklma her zaman olduu gibi parlak bir fikir geldi. Dnte evremdeki nesnelerin programlama dillerindeki etkilerini dnecektim. evremizde ne kadar ok nesne var. iekler, bcekler, insanlar, arabalar, otobsler, kular, talar, kayalar...Bu liste o kadar kabarkki saymaya kalkmak bile sonsuzlukla arpmak gibi bir ey olsa gerek. Her nesnenin belli bir takm zellikleri, ilevsellikleri ve hatta amalar var. Baz nesneler bir araya gelerek baka yeni nesnelerin domasna neden olurlarken onlara bir takm ortak zelliklerinide veriyorlar. Ayn insanlarn bir araya gelerek evlenmesi, ocuk sahibi olmas ve ocuklarna kendi zelliklerinden bir takm kaltmlar brakmas gibi. Baz nesneler kendi iinde kapal, sahip olduu deerleri deitirilemeyen ama gzlemlenebilen trden. Baz nesneler ufak deiikliklere urayarak baka nesnelere ilham kayna olmular. Bu eitlilik altndaki tm neselerin ortak zelliklerini bir arada dnmek ve bir kenara koymak onlar bu ortak niteliklerine gre snflandrmaktan baka bir ey deil. Otomobilleri bir snf altnda dnebiliriz. Her otomobil 4 tekerlekli, motoru olan, ileri geri hareket edebilen, direksiyona sahip ve benzinle alan, gaza basldnda viteste ise hareket eden, frene basldnda duran ve bunlar gibi pek ok ortak zellie ve ileve sahip olan birer nesne. Ama bu snfa ait tm nesneler bir birlerinden farkl olabilecei gibi birbirlerinin aynsda olabilir. Otomobil firmalarnn arabalarn dndmzde, hepsinin farkl zelliklere sahip ama temel ilevsellikleri neredeyse ayn olan nesneler olduklarn syleyebiliriz. Hatta retim hattndan yeni km tm gri renkli opel vectra 1.6lar motor seri numaralar hari birbirlerinin ayns olan nesnelerden oluan bir nesne koleksiyonundan baka bir ey deildir.

47

te gerek hayattaki nesnelerin bizler iin anlam ve nemi neyse, nesneye dayal bir programlama dili iinde nesnelerin anlam o derece nemlidir. Hereyden nce, bu dillerde btn kavramlar, nesnelere ve dolaysyla bu nesneleri oluturmak yada rneklemek iin kullanlan snflara baldr. Dnn ki object snf deilmidir C# dilinde ve hatta Javada en st snf. Java programlama dilide tam anlamyla nesneye dayal bir dil. Dolaysyla nesneleri kullanan bir dil. Nesneleri, sahip olduklar zellikleri, deerleri ve ilevleri ile kullanan bir dil. Bu dnceler eliinde geri dn yolunu tamamladm. Artk eve dnme vaktim gelmiti. u andan sonra yaplacak en gzel ey, eve gitmek scak bir du almak ve Pazar sabahnn gazetelerini okuyup gne merhaba demekti. Ama ne yazkki byle olmamt. imdeki korkun renme al, gazete yerine Java ile ilgili kaynaklar aratrmama neden oldu. Ama her zaman olduu gibi yanmda scak bir kahvem vard. Uzun sre camdan dar bakarak snflarn yerini dndm ve onlar daha iyi anlamaya altm. Gerektende Javadada dier nesneye dayal programlama dillerinde olduu gibi herey snflar zerine kurulu idi. Dolaysyla snflar ok iyi kavramak programlama dilini renirken yaadm srete ok ama ok nemliydi. nemli olan sadece snflarn nasl yazldn renmek neleri ihtiva edeceini bilmek deildi. Snflar en uygun ekilde, en etkin ve verimli ekilde kullanabilmekte ok nemliydi. Sz gelimi, bu gn .net dilinde, veritabanlarndaki veriler ile almak iin inanlmaz kabiliyetli ve yetenekli snflar vard. Java iinde bunlarn benzerlerini yazmak istememiz bu tip snflar tasarlamamz anlamna geliyordu. Veya veritabanlarndan okuduumuz veri satrlarn dnelim. Bunlar birer snf nesnesi olarak uygulamamza yerletirmek , ilemlerimizi dahada kolaylatrmazmyd. Veritabanna balanr istediimiz satra ait verileri uygun bir snf nesnesine aktarr ve bunlar tekrar veritabanna gnderinceye kadar bal olmak zorunda kalmazdk. Ayn DataSet kavram gibi. Ama daha sade, daha kolay ve belkide daha etkili. Elbette Java dilinde veritabanlar ile ilgili ne tr ilemler yapabileceimi ne tr kabiliyetlere sahip olduumu u an iin bilmiyorum ama ileride bunlar renmek iinde can atyorum. Ama u an iin yapacam snflarn nasl oluturulduunu ve
48

kullanldn anlamak olucak. Java dilini renmeye devam ettike sanyorumki snf kavramn ok daha iyi kavrayacam. Geri, bu kavrama C# dilinden olduka aine ve hakimim. Ama Sunn belkide bilmediim srprizleri vardr bu konuda. Neyse deneyip greceiz. Normalde kendimce bu kadar ok konumam. Aslnda daha az sz ve daha ok hareket taraftarymdr. Eeee atalrmz ne demi; nerde hareket orda bereket. Tipik bir uygulamac ite. O bakmdan makinemin bana geip ilk snfm yazsam iyi olucak sanrm. imdi bir uygulama gelitirmek istiyorum. Bu uygulama hayali olarak bir tablodan bir ka satr veri alsn istiyorum ve sonra bu verileri birer nesneye aktarmak istiyorum. Bu amala ncelikle kafamda hayali bir tablo tasarladm ve sonrada bu tablonun satrlarn birer snf nesnesi olarak nasl tasarlayabileceimi dndm. Aslnda iin tasarm ksmnda hep bir eyler izmek, dnceleri kada dkmek en gzelidir sanrm. Bunun iin aslnda ok gzel bir yap var. UML. Fakat ben buradaki ekilleri ezberlemekten ve unutmaktan bktm. O nedenle baka birisine eklimi gstermediim srece genelde kendi kafamda oluturduum izelgeleri kullanrm. Sanrm buna ben BML diyeceim. Dier yandan izdiklerimin bakalar tarafndan kolayca anlalmas iinde dikkat ediyorum.

49

Aslnda yapmak istediim ey ok basit. Tablodaki satrlar alp, Snf nesneleri haline getirmek. Bunu yaparken, tablodaki alanlarn deerlerini, snfm iinde oluturacam deikenlerde saklyacam. Bu durumda, snfmdan nesneler trettikten sonra, iindeki deikenlere deer atamam salyacak ilevlere ihtiyacm olucak. Ayrca program iinde, bir nesneye ait bu alan deerlerini deitirmek isteyebilirim. Bunun iinde bir veya bir ka metoda ihtiyacm olabilir. Artk ne yapmak istediimi bildiime gre kodlar yazmaya balamann zaman geldi. Ne yazkki yine skc Notepad editormze dneceiz. Aslnda buna bir are bulmam lazm. Java programlarn yazabileceim cretsiz bir yazlma ihtiyacm var. Aslnda kaynaklarmdan en iyi java editrnn Borland firmasnn JBuilder rn olduunu renmi bulunmaktaym. stelik bu rnn Personel srmde cretsiz olarak datlyormu. Sanyorum bu leden sonra vaktimi ayrp bu srm internetten indirmek iin kullanabilirim. Ama imdilik notepad ile devam edeceim. Evet ncelikle bana, oluturacam nesneleri rneklendireceim bir snf lazm. Zaten Javay renmeye baladmdan beri, mutlaka snf tanmlamalarn yapyoruz, nitekim Java dilide dier nesne ynelimli diller gibi, nesnelere dolaysyla snflara dayanyor. O halde ne duruyoruz. e snfmz oluturmakla balayalm. public class SinifKisi { } Elbette snf bylesine tanmlamak son derece anlamsz ama birazdan snfn iine koyacamz yeler ile baya bir yol katedeceiz. Biz oluturduumuz bu snfta treteceimiz nesneler ile, tablomuzdaki satrlar temsil ediceksek eer, tablodaki alanlarda temsil etmemiz gerekir. te bunun iin snfmz ierisinde, tablodaki alanlara denk gelicek alanlar tanmlayacaz. Bu alanlarn zel yan private olarak tanmlanacak olmalar. Bunun sebebi, her zamanki gibi kapslleme (Encapsulating). Kapsllleme sayesinde, snfmz iinde kullandmz alanlarn dardan her hangibir etki ile dorudan deitirilemelerini engellemi oluyoruz. Bu durum
50

bizim isteimiz dnda oluabilecek atamalarn nne gememize ve illede bu alanlarn deerleri deiecekse bizim belirlediimiz bir izgide olmasna neden oluyor. Bu da programclkta ve zellikle nesne ynelimli programlamada ok byk bir yere sahip olan Kontroln elimizde olmasn salyor. Aslnda kapsllemeyi , itiimiz kapsl eklindeki ilalardan yola karak daha iyi anlayabiliriz. ou zaman kapsl eklinde ilalar ieriz. Bu ilalarn dndaki koruyucu kapsl iinde, binlerce belkide onbinlerce zerrecik yer alr. Bu zerreciklerin byle bir kapsl iine alnmasndaki en byk neden bir arada tutulmak istenmeleri olarak dnlebilir. Ayn snflarmzda kullanacamz alanlar bir arada tutmamz gibi. Dier yandan, kapsllenmelerinin en byk nedeni, istenilen hedefe kadar gidilecek yol zerinde (az, tkrk bezleri, yemek borusu, mide vesaire...) karlalabilecek ve zerrelerin istenmeyen ekilde vcuda karmasna neden olucak etkilerden korunmaktr. Ama ilacn istenen yerde kapslnn istenen etki ile eriyerek, zerreciklerin serbest kalmasdr. Elbetteki kapsl ila rnei snflardaki kapsllemeyi tam olarak aklayamaz, ancak ok byk benzerlikler tar. te snflarmz yazarken de, bu snflar iierisinde tanmlanan ve snfa ait nesneler tarafndan eriilebilen alanlarn, bizim programladmz etkiler dnda deitirilmesini istemeyiz. Bir alann sadece okunabilir olmasn veya, bu alandaki deerlerin bizim kontrolmz altndaki metodlar ile deitirilmesini isteyebiliriz. te bu uyumu salamak iin, nesneler tarafndan kullanlan ve snf iinde tanmlanan alanlar private olarak belirtiriz. Bylece bu alanlara sadece tanmlanm olduklar snf ierisinden eriilebilecektir. imdi uygulamamzda, tablo alanlarn temsil edicek snf ii zel alanlarmz oluturalm.

public class SinifKisi { private int fID; private String fAd; private String fSoyad; private String fTelefon;

51

} imdi C# ile bu snf yazyor olsaydm bu alanlar iin birer zellik tanmlar ve get ile set bloklarn oluturudum. Ancak kaynaklarma baktmda artc bir ekilde bu tarz ifadelerin, yani get ve set blou olan tarzda zelliklerin yer almadn grdm. Belki bu gzmden kamt ama tekrar baktmda iyice emin oldum. zellik tanmlamalar yerine, zelliklerinin rollerini stlenecek olan metodlar kendimiz yazyorduk. Aslnda bu tuhafma gitti. Neyse yapacak bir ey yoktu, yeni bir fincan kahve almaktan baka. e koyulma vakti. Hereyden nce bu alanlarn deerlerinin deitirilebilmesini istiyorum ayn zamanda deerlerinin okunabilmesinide. O zaman her biri iin birer metod yazmam gerekiyor. public class SinifKisi { private int fID; private String fAd; private String fSoyad; private String fTelefon; public int getID() { return fID; } public String getAd() { return fAd; } public String getSoyad() { return fSoyad; } public String getTelefon() { return fTelefon;

52

nce alanlarn deerlerini snf rnekleri olan nesneler zerinden okuyabilmek iin, her bir alan iin bir metod yazdm. Bu metodlarn tek yapt return anahtar kelimesi ile geriye, private snf alanlarnn deerlerini gndermek. Tabi burada nemli olan nokta, bu metodlarn dn deerlerinin, private alanlarn veri tipleri ile ayn olmalar. Bununla birlikte bu metodlar, snf dndan kullanabilmek iin yada bu snfmzdan treteceimiz nesnelerde kullanabilmek iin public belirteci ile tanmlyoruz. Sra geldi bu alanlarn deerlerini deitirecek metodlara. Hereyden nce, fID alanmz aslnda, tablomuzdaki ID isimli birincil anahtar alann iaret ediyor. Tablomuzun bu deerinin kullanc tarafndan deitirilmesi kesinlikle istenmeyecek bir durum. Ancak dier yandan bu alana ait deerleri okumak isteyeceimiz, rnein where sorgularnda kullanmak isteyeceimiz durumlarda olucak. te kapsllme iin bir neden daha. public class SinifKisi { private int fID; private String fAd; private String fSoyad; private String fTelefon; public int getID() { return fID; } public String getAd() { return fAd; } public void setAd(String ad) { fAd=ad;

53

} public String getSoyad() { return fSoyad; } public void setSoyad(String soyad) { fSoyad=soyad; } public String getTelefon() { return fTelefon; } public void setTelefon(String telefon) { fTelefon=telefon; } } Artk bir yerler gelmeye baladk. Ancak snfmzda halen daha eksik yeler var. Hereyden nce, bir nesneyi yaratmann en temel yolu new anahtar kelimesini kullanmak. Bu anahtar kelime, tanmland snf iin bir yapc metod arr. Yapc metodlar, ounlukla snf rnei olan nesneleri ilk kullanma hazrlarken kullanlr. rnein, snf iinde kullanlan alanlara balang deerlerinin verilmesi ve benzeri ilemler iin. Bir snf iin birden fazla yaplandrc tanmlayabiliriz. Bu, yaplandrc metodlarn ar yklenmesi ile mmkn olur. Ar ykleme bildiiniz gibi, bir metodun ayn isim altnda farkl ilevler iin kullanlmasdr. Burada ayn isimli bu metodlar birbirinden ayran, kullanlan parametrelerin farkllklardr. C# dilinde olduu gibi ar ykl metodlarn ayr ekilde alglanmalar hem metod parametrelerine hemde metodun dn tipine baldr. Oysa Javada durum farkldr. Javada ar ykl metodlar sadece parametreleri ile ayrt edilebilir, metodlarn dn tiplerinin, metodlarn ayrt edilmesinde bir etkisi yoktur.

54

Snfmz gelitirmeye devam etmeden nce ar ykl yaplandrclarn bir snf iinde nasl kullanldna dair bir rnek verelim. public class OverloadM { private int deger1; private int deger2; public OverloadM() { deger1=10; deger2=15; } public OverloadM(int d1,int d2) { deger1=d1; deger2=d2; } public OverloadM(int d1) { deger1=d1; } public void Yaz() { System.out.println("Deger1:"+deger1+" Deger2:"+deger2); } } Burada OverloadM isimli snfmzda, adet yaplandrc metod yer almaktadr. Bunlar kullanacak olan snfmz ise Program snfmz olup kodlar aadaki gibi olucaktr. public class Program { public static void main(String[] args) { OverloadM birinciNesne=new OverloadM(); birinciNesne.Yaz();

55

OverloadM ikinciNesne=new OverloadM(18,24); ikinciNesne.Yaz(); OverloadM ucuncuNesne=new OverloadM(45); ucuncuNesne.Yaz(); } } Bu iki snf baar ile derledikten sonra, Program.java isimli uygulamay altrdm. Sonu aadaki gibi oldu.

Grld gibi yapc metodlarmzda dikkat eken ilk zellik, snf ad ile ayn olmalar. Ancak burada karlatm ilgin bir durum oldu. Yapc metodlarn nasl kullanld ile urarken, varsaylan yaplandrcy tanmlamadm aadaki rnei yazdm. public class OverloadDeneme { private int deger1; private int deger2; public OverloadDeneme(int d1,int d2) { deger1=d1; deger2=d2; } public OverloadDeneme(int d1) { deger1=d1; }

56

public void Yaz() { System.out.println("Deger1:"+deger1+" Deger2:"+deger2); } } public class Prog { public static void main(String[] args) { OverloadDeneme Nesne=new OverloadDeneme(); Nesne.Yaz(); } } Prog isimli snfm derlemeye altmda aadaki hata mesaj ile karlatm.

Bir anda ne olmutuda, new yaplandrcs ile basit bir nesne yaratma ilemi hata ile sonulanmt. Heyecanla ve birazda tedirgin bir havayla, kaynaklarm hzl hzl kartrmaya baladm. Sonrada Javann ok gzel inceliklerinden birini farkettim. Normalde Java, varsaylan yapc metodlar bir snf iin yazmassak bizim iin bir tane hazrlyordu. Ancak zelletirilmi (parametreler alan) yapc metodlar tanmladmzda, bizim tam anlamyla konunun hakimi olduumuzu dnerek bu varsaylan yaplandrcy otomatik olarak tanmlama desteini bir anda ekiveriyordu. Tabir yerinde ise bizimle bu konuda muhatap bile olmuyordu. Dolaysyla varsaylan yapc metoduda bizim tanmlamamz

57

gerekiyordu. Bu gzel incelikten yola karak uygulamay dzelltim ve hata mesajn ortadan kaldrdm. C# dilini renmeye ilk baladm zamanlar niversite yllarnda rettikleri C++ dilindeki byk kk harf ayrmnda her zamanki gibi ilk balarda ok unutkanlklar yaam ve hep hatalar yapmtm. Ama imdi Javada grdmk, unutkanla asla yer yok hatta tam anlamyla dile hakim olmak esas. Neyse yaplandrclarn bu zellikleri ve ilevlerinden sonra, acaba kendi snfmz iin zel bir yaplandrcya gerek var m diye dnmeye baladm. Bu snfa ait nesneler, tablo satrlarn gsterecek olduundan, yaplandrclara parametre atayp, alan deerleri ile oynamak son derece anlamsz geldi. Bu nedenle bir yaplandrc yazmaktan vazgetim. Ha bu durumda, hi bir yaplandrc yazmadm iin, bu iin kontroln Javaya brakm oldum. O benim iin varsaylan bir yaplandrc oluturacak ve bylece ben uygulamamda new anahtar kelimesi ile rahata nesneler yaratabileceim. Dier yandan, snfmz iine baz metodlarda eklenebilir. rnein, tm alan deerlerini dzenlediimizi dnelim. Bunun iin bir metod yazabiliriz. Hatta ayn isimli metodu her bir alan iin ayr ayr uygulayarak, alanlarn bireysel olarak dzenlenmesinede imkan salayabiliriz diye dnrken bu iler iin metodlar(set ile balatan metodlar) yazdm farkettim. Ancak toplu bir dzenleme iin gzel bir metod yazlabilirdi. Bylece snfa aadaki metodu eklemeye karar verdim. Bu metod snf iindeki alanlarn deerlerini deitirecek. public void Degistir(String ad,String soyad,String telefon) { fAd=ad; fSoyad=soyad; fTelefon=telefon; } Bu metodun tek yapt, parametre olarak ald String veri trndeki deerleri alarak, snf iindeki alan deerlerine atamak. Sanyorumki snfmn yaps temel olarak bu ekilde olucak. Artk bu snf ve bu snfa ait nesneleri kullanacam bir rnek uygulamaya ihtiyacm var. Bu uygulamada elbette bir
58

snf eklinde tasarlanacak ve mutlaka main metodu olucak. Main metodu, bir snf iin balang noktas niteliindedir. Ama tabiki tahmin edeceiniz gibi uygulama ierisinde sadece bir snfn main metodu olmaldr. Bu bilgiler nda, aadaki rnek snf hazrladm. public class Uygulama { public static void main(String[] args) { SinifKisi k1=new SinifKisi(); k1.setAd("Burak Selim"); k1.setSoyad("SENYURT"); k1.setTelefon("0000000"); System.out.println(k1.getAd()+" "+k1.getSoyad()+" "+k1.getTelefon()); k1.Degistir("Burak S.","SENYURT","444 44 44"); System.out.println(k1.getAd()+" "+k1.getSoyad()+" "+k1.getTelefon()); } } Bu kk uygulamada, SinifKisi snfndan k1 isimli bir nesne tanmlyor ve alanlarnn deerlerini deitirebiliyoruz. Uygulamay altrdmzda aadaki sonucu elde ederiz.

Bu noktada merak ettiim, snf iindeki zel alanlara erimek istediimde nasl bir sonu alacamd. O nedenle kodlara aadaki satrlar ekledim. Burada ak bir ekilde zel alanlara, tanmlam olduum nesne vastasyla erimeye alyordum. Bakalm derleyici ne yapacak. System.out.println(k1.fAd+" "+k1.fSoyad+" "+k1.fTelefon);

59

Sonuta uygulamay derlediimde aadaki hata mesajlar ile karlatm. Kapslleme gereklemiti. Alanlar dardaki snflardan soyutlamtm. Onlara sadece benim tanmladm metodlar vastasyla eriilebilecekti.

Aslnda snflar ile ilgili daha pek ok kavram vard kaynaklarmda. rnein, static metodlar. Bu metodlar her nesne ynelimli programlama dilinin nemli bir paras bence. Bir static metoda ne zaman ihtiya duyabilirdik? Static metodlar, tanmlandklar snfn rneklendirilmi nesnesine ihtiya duymadan alabilen metodlardr. Dolaysyla byle bir metodu kullanabilmek iin, bu metodun tanmland snfa ait bir nesne yaratmak zorunda deiliz. Dorudan bu metodun tanmland snfa ve pakete nokta notasyonlarn uygulayarak, bu static metodu altrabiliriz. Bylece sistem kaynaklarn zellikle gereksiz nesnelerle doldurmam oluruz. rnein matematiksel ilemlerin yapld metodlar gz nne alalm. Bir say dizisindeki elemanlar sralayan bir metod varsayalm. Bu metod mutlaka ve illaki bir paket iindeki snf iinde yer alacaktr. nk nesneye dayal programlama dillerinde herey nesne modeli zerine kuruludur ve tm yeler snflar ierisinde, snflarda belli paketler ierisinde yer alr. Paketler ile ilgilide pek ok kaynak buldum. Akas bir kahve molasndada onlar ile ilgileneceim. Javadaki paketlerin yerleimi aslnda kitaplardaki anlatmlar tarzyla biraz gzm korkuttu diyebilirim. Ne demitik bir say disizini sralayan metodumuz olsun. Bu metodun tek yapaca i, parametre olarak ald dizinin elemanlarna bir srlama algoritmas uygulamak ve sonucu bir dizi olarak dndrmektir. Bu ii
60

yapmas iin bir nesneyi grevlendirmek sistem kaynaklarnda sadece but sralama metodu iin yer amak anlamna gelir. Oysaki metodumuzu static olarak tanmlarsak, nesne yaratmaya gerek kalmayz. Metodumuzu ise snf.metod notasyonu ile rahatlkla kullanabiliriz. Bu dnceler nda acaba kk uygulamama bu tip bir static metodu nasl uygulayabilirim diye dnmeye baladm. Aklma bir metod geldi. rnein SinifKisi isimli snfa ait nesneleri ekrana dzgn bir ekilde yazdracak bir metodum olsayd. Aslnda bu metodu SinifKisi iine yerletiripte arabilirim. Ama ama static metodlar anlamak olduu iin baka bir snf iine almaya karar verdim. te o snfn kodlar. public class Yazmaca { static void KisiYaz(SinifKisi { System.out.println("Kii System.out.println("Kii System.out.println("Kii } }

k) ad "+k.getAd()); soyad "+k.getSoyad()); telefonu "+k.getTelefon());

Bir static metod tanmlama iin yaplacak tek i metodun tanmlanmasna static anahtar kelimesini eklemek. Buradaki metod parametre olarak SinifKisi snf tipinden bir nesne rnei alyor. imdi Uygulama.java dosyamn kodlarn aadaki ekilde yeniledim. public class Uygulama { public static void main(String[] args) { SinifKisi k1=new SinifKisi(); k1.setAd("Burak Selim"); k1.setSoyad("SENYURT"); k1.setTelefon("444 44 44"); SinifKisi k2=new SinifKisi();

61

k2.setAd("Sefer"); k2.setSoyad("ALGAN"); k2.setTelefon("555 55 55"); SinifKisi k3=new SinifKisi(); k3.setAd("Ahmet Faruk"); k3.setSoyad("NACAROGLU"); k3.setTelefon("666 66 66"); SinifKisi[] kisiler=new SinifKisi[3]; kisiler[0]=k1; kisiler[1]=k2; kisiler[2]=k3; foreach(SinifKisi kisi in kisiler) { Yazmaca.KisiYaz(kisi); } } } Uygulamadaki kodlar bir anda gzme ok gzel grnd. tane SinifKisi nesnesi yaratp alanlarn deerlerini deitirmi ve blyece, farkl SinifKisi nesnesine sahip olmutum. Dier yandan bu nesneleri SinifKisi tipinden bir diziye aktarm ve bu dizi iindeki her bir eleman bir foreach dngsnde ele alarak, static KisiYaz metodunu armtm. Herey ok gzel olacak gibi grnyordu. Ama yle olmad. Bam diye bir hata aldm.

62

Uzunca bir sre dndm. Acaba yanl bir yazmm uyguladm diye. Ama sonra dkmanlarmda bu ii aratrmaya baladm. Kimse c# taki gibi bir foreach dngsnden bahsetmiyordu. Acaba byle bir dng ifadesi yokmuydu? Ta taaaa.. Hakkatten aradm taradm dkmanlarda bunu bulamadm. Belki baka bir ekli vard. Bu amala elimdeki e-book lardan OReilly basm 6000 sayfalk java dkmanna baktm. Buradada foreach gibi bir dngden bahsedilmiyordu. Sadece For dnglerini bulabildim. Araym bittikten sonra, madem yle olmuyor bende normal bir for dngs kullanrm dedim ve kodlar aadaki gibi deitirdim. public class Uygulama { public static void main(String[] args) { SinifKisi k1=new SinifKisi(); k1.setAd("Burak Selim"); k1.setSoyad("SENYURT"); k1.setTelefon("444 44 44"); SinifKisi k2=new SinifKisi(); k2.setAd("Sefer"); k2.setSoyad("ALGAN"); k2.setTelefon("555 55 55"); SinifKisi k3=new SinifKisi();

63

k3.setAd("Ahmet Faruk"); k3.setSoyad("NACAROGLU"); k3.setTelefon("666 66 66"); SinifKisi[] kisiler=new SinifKisi[3]; kisiler[0]=k1; kisiler[1]=k2; kisiler[2]=k3; for(int i=0;i<=2;++i) { Yazmaca.KisiYaz(kisiler[i]); } } } imdi oldu ite. Uygulamay altrdmda aadaki sonucu elde ettim. Static metodum olan KisiYaza dorudan snf ismi zerinden erimeyi baarabilmitim.

Snflar ile ilgili ilenecek daha pek ok kavram vard aslnda. Snflar aras kaltm, ok biimlilik gibi. Ama kahvemde tkenmiti. Bir sre dinlenmeye ve kaynaklarm okuyarak yeni bilgiler edinmeye karar verdim. Kim bilir bir sonraki kahve molamda, hangi rzgarlara kaplacak, hangi memleketlere liman acaktm. En azndan artk snflarn Javada nasl yazldklarn biliyordum. Metodlarn, zel alanlarn, static metodlarn, yaplandrclarn...Ama katedilecek daha ok yol vard. Aslnda gnlmden geen, bu uygulamda gerekten
64

veritabanna balanp bir tablodan alanlar alabilmekti. Fakat yolum ok uzun ve sabretmek lazm. Javada veritabanlarnn ilenmesini ok ama ok merak etmekle birlikte nmde bilmem gereken, Paket kavram, appletler, guiler gibi pek ok konu var. Hadi rast gele diyelim. Blm 5: Paketler Kargoda Offf, Kollarm koptu bu paketleri tamaktan. Bugn, markete kadar yryp bir ka bir ey alaym dedim eve. Ama gidince habire evdeki bir eksik geliveriyor insann aklna. Marketlerin insan psikolojisi zerindeki etkileri ite. Hereyi almak istiyor insan. Neyse sonunda fazla harcama yapmadan (birazda kendimi tutarak) evime gelebildim. Ama bu paketleri tamak kollarm baya bir kaslandrd. Paketleri mutfak tezgahnn stne braktm ve onlara yle bir iki saniye duraksayarak baktm. Hafta boyunca, Javadaki paket kavramn incelemeye almtm. Sanrm, market paketleri ile aralarnda bir ba kurmaya alyordum. Ama sonra kendime geldim ve bylesine bir ruhsal bunalma girmeye hi gerek olmadna karar vermeyi baarabildim. Sonuta market paketleri market paketleriydi ite. leri bitince pe attm gitti. Ya Java paketleri...Hafta boyunca bu konuyu inceledim. Sonuta elbette buradaki paket kavram ok tandk geldi. Framework iin namespace(ad alan) kavram ne ise, paket kavramda Java iin oydu. Sonu olarak, paket kavram iin kafamda yle bir tanm oluturdum. Ksa ve etkili bir tanm. Paket, iinde snf(lar) barndran bir sistem yesidir. Bu tanmdan ksaca paketlerin, ierisinde bir ok snf barndrd sonucuna varabiliriz. Ama iin nemli ksm paketlerin bize salam olduu avantajlar iyi bilmekti. te bu noktada kaynaklarmdan edindiim bilgiyi ekle dkmeye karar verdim. nanyorumki bir resim bin kelimeye bedeldir. O yzden programlama dillerini renirken, bu tarz temel kavramlarn ekiller ile birlikte aklanmas her zaman iin renmemi dahada kolaylatrmt. rnein, ado.net ierisindeki snflarn ekiller ile ifade edilmesi gibi. Bu bakmdan, Java paketlerinin
65

amalarn aklayabilecek bir ekil zerinde altm. Burada bir eklin daha iyi olaca kansna varmamda aslnda, Yzklerin Efendisi lemesinin nemli bir payda var. Gnlerden bir gn bir gece vakti, ben askreken, izinim bitmesi nedeni ile Ankaraya dnyordum. Yolda gece vakti sessizlikte kitap okumak her zaman houma gider. O gnde Yzklerin Efendisi filminin ilk blmn anlatan kitap elimdeydi. Okumaya baladm ama ksa bir sre sonra braktm. nk hobitler, urakhailer, elfler, gandalf filan birbirlerine karmt. Bir baktm ki bir cmleyi iki kere okuyorum konuyu anlayabilmek iin. Bu byle olmayacak dedim ve ertesi akam karargahta grevim bittikten sonra, Kzlayda bir cep sinemasna giderek filmi izledim. nann her eyi ok daha iyi anlamtm. te bu nedenle konuyu kavramnn bazen en iyi yolunun resimler olduuna inanrm. Sz bu kadar uzatmannda anlam yok hani. te paket kavramnn gerekleri.

ekil aslnda paket kavramn iyi aklyor. Bir paket ierisinde snflar olduunu biliyoruz. Ama ilk ama ayn konularn amalarna hizmet eden snflar bir araya toplamaktr. rnein

66

Matematik Paketinde temel ilemleri barndran Aritmetik Snf, toplama, karma, arpma gibi temel aritmetik ilemleri yaparken, Trigonometri snf ise, sin,cos,tan gibi trigonometrik fonksiyonlar zerinde younlar. Ayn ekilde Kompleks snfda, kompleks saylarn ilevleri ile ilgilenir. Dier yandan sadece izim ilemleri iin kullanabileceimiz snflarda Grafik Paketinde toplayabiliriz. Bylece paketlerin ilk amacna ulam oluruz. Ayn konulu amalar zerinde younlaan snflar bir at altnda birletirmek. Dier yandan, her iki paket iinde A Snf isimli birer snf vardr. Bunlar ayn isimli snflardr. Ancak farkl paketler ierisinde tanmlandklar iin, bir uygulamada her ikisinide kullanma lksne sahibizdir. Tabi burada kullanmda dikkat edilecek bir iki husus vardrki bunlar rnekleri yapmaya baladmda daha iyi anlayacamz dnyorum. Demekki paketlerin ikinci nemli amac, ayn isimli snflarn sistem ierisinde kullanlabilme imkanna sahip olunmas olarak syleyebiliriz. Bir de nc fakat zaten her tanmdanda kartlabilen bir ama vardr. O da paketleri oluturarak snflarn bir at altnda birlemesi ve sonradan bu paketlerin kolayca yer deitirerek farkl platformlara btn halinde tanabilmeleri. Bu aslnda olduka ilgin materyallerin Javada kullanlmasna neden olmu bir ama. Bu amacn sonucu JAR dosyalar olumu. Olduka gizemli ve gzel bir kavram. Sk durun ilerledike ondanda bahsedeceim. Gelelim Java ile paketlerin nasl tanmlandna. Bunun iin package anahtar kelimesi kullanlyor ve paketler oluturuluyor demeyi ok isterdim. Ancak olay sadece package tanm ieren bir dosya oluturmak deil. Bunun dnda paketin isimlendirilmesi ile ilgili gzel bir kural mevcut. bu kurala uymaklada kalmyor sistemdeki CLASSPATH ayarlarnnda bu kurala uygun ekilde yaplandrlmas gerekiyor. te bu bilgiler ndan hareketle, ilk nce isimlendirme mantna bir gz atmann uygun olacan dndm.

67

Javada paketleri isimlendirmek iin, ounlukla internet alan adlarnn isimlendirilme mant kullanlyor. Internetteki her alan ad birbirinden bamsz olarak oluturulmutur. Buda onlarn benzersiz olmalarn salamaktadr. te bu dnceden hareket ederek, Java dilinde bir paketi isimlendirmek iin, yine bu alan ad mant kullanlmaktadr. Hatta Java SDK ile birlikte gelen paketlerde bu isimlendirmeyi kullanr. rnein java.awt.image veya org.omg.CORBA gibi. te bende ilk paket rneimi olutururken bu isimlendirme mantn kullancam. Dier yandan yaplan bu isimlendirmenin bilgisayarmzda fiziki olarak adreslenmesi gerekiyor. Peki bu nasl mmkn olucak? te burada, paket ismimizdeki . ile ayrlan tm elemanlar iie klasrlek eklinde oluturmamz ve paket dosyamz en alttaki klasrde yaratmamz gerekiyor. te byle demeyi gene ok isterdim ama yine i bitmiyor. nk oluturulan pakete, sistemdeki baka fiziki konumlardanda eriebilmek iin CLASSPATH ayarlarn yapmak gerekiyor. te bu bilgileri inceledikten sonra hemen ilk paketimi yazmaya koyuldum. Bu amala imdi yapacam ve sonradan oluturacam paketler iin sistemimde ortak bir klasr oluturdum. reteceim tm paketleri bu klasr altnda toplayacam.

lk paketim iine, s alma gibi ilemleri ierecek bir snf koymay dnyorum. Bunun gibi matematiksel ilemler ile ilgilenecek bir ka snf daha koyabilirim. Bu amala oluturacam pakete aadaki adlandrmay uygulamaya karar verdim. com.bsenyurt.mat Bu arada unuda not olarak belirtmekte fayda var. altm kaynaklarn tm, paket isimlendirmelerini yaparken internet alan ad mantn tersten yazarak uyguluyorlar. rnein www.csharpnedir.com adresini baz alarak bir paket oluturmak

68

istediimizi dnelim. Bu durumda com.csharpnedir.pkg gibi olabilir.

isimlendirmemiz,

lk paketim iin oluturduum bu isimlendirmenin aynsn, paketleri toplayacam klasr ierisindede fiziki olarak oluturmam gerekiyor. Yani klasr yaps u ekilde olucak.

imdi paket tanmn ierecek olan java dosyamz bu klasr ierisine oluturabiliriz. Bu amala, aadaki kod satrlarn ieren java dosyasnn oluturdum. Burada tanmlanm olan public snf adnn, dosya ad ile ayn olmas gerekmektedir. package com.bsenyurt.mat; public class Ussel { public double usal(double sayi,double usDegeri) { double toplam=1; for(int i=1;i<=usDegeri;++i) { toplam=sayi*toplam; } return toplam; } } Bu kodlarda package tanmn oluturduumuz klasr sistemi ile ayn olduuna dikkat edelim. Ayrca dosyamz public snfmzn ismi ile kaydediyoruz. Uygulamamz derlediimizde, Usler.class dosyasnn baarl bir ekilde oluturulduunu grrz.

69

Artk paketimizi oluturduumuza gre bunu kullanmann zaman geldi. Bunun iin paketin bulunduu klasrden alakasz bir yerde yeni bir uygulama yazmaya karar verdim. Amacm buradan, yazm olduum paket iindeki Usler snfna ve oradanda usAl metoduna erimek. Bunun iin, sistemde C:\JavaSamples\PaketUygulamasi\ adresinde bir java dosyas oluturdum. Bu dosyaya aadaki kodlar ekledim. import com.bsenyurt.mat.*; public class Uygulama { public static void main(String[] args) { Ussel u1=new Ussel(); double sonuc=u1.usal(2,4); System.out.println(sonuc); } } lk dikkati eken nokta paketimizin import anahtar szc ile uygulamamza eklenmesi. Bu ekilde, bu paket ierisindeki Usler isimli snfa erimeyi umut ediyorum. Ancak bu noktada uygulamay derlediimde aadaki hata mesajlar ile kar karya kaldm.

70

Hata mesajlarnn anlam ortayd. Java derleyicisi, import etmek istediim paketi bulamyordu. Java derleyicisinin bu paketi bulabilmesi iin, sistemdeki CLASSPATH evre ayarn deiitirmem ve derleyiciye bu paketin yerini sylemem gerekiyor. Bunun iin xp iletim sistemine sahip bilgisayarmda My Computer simgesine sa tklayp Propertiese buradanda Advanced Options ksmna geldim. Daha sonra, Environment Variables ksmnda, gerekli CLASSPATH tanmn ekledim. Burada nemli olan com.bsenyurt.mat paketinin iinde bulunduu klasrn eklenmesiydi.

71

Bylece Java derleyicisine import anahtar szc ile eklenen paketi D:\Java\Paket\ klasr altnda aramas gerektiini sylemi oluyoruz. imdi Uygulama.java programn derlersek, uygulamann baar ile derlendiini ve altn grrz.

Herey gzel gidiyor. Ama biz bu pakete baka bir snf daha nasl ekleyebiliriz? Bunun iin, oluturacamz yeni snf, varolan paketimiz iinde tanmlamalyz. Aadaki rnekte olduu gibi.

72

package com.bsenyurt.mat; public class Temel { public int Toplama(int ilksayi,int ikincisayi) { return ilksayi+ikincisayi; } } Bu rnek ile, com.bsenyurt.mat isimli pakete Temel isimli snfmzda eklemi oluyoruz. lk nce package tanmlamasnn yaplmas ile, izleyen public snfn bu package tanmndaki paket iin oluturulduunu belirtmi oluyoruz. Tam bu srada aklm, C#taki namespace(ad alan) kavramna gidiyor. C# ta bir namespace tanm altnda birden fazla snf belirtebiliyoruz. Acaba Java iinde bu geerlimi diye merak ediyor ve Temel snfn olduu kodlara baka bir public snf ekliyorum. package com.bsenyurt.mat; public class Temel { public int Toplama(int ilksayi,int ikincisayi) { return ilksayi+ikincisayi; } } public class Log { public void LogAl() { System.out.println("Logaritma alyor..."); } }

73

Ancak program derlediimde aadaki hata ile karlatm. Public Log snfnn farkl bir dosyada olmas gerektiine dair bir hata mesaj almtm.

Fakat bu snf public belirteci olmadan tanmladmda ise, package com.bsenyurt.mat; public class Temel { public int Toplama(int ilksayi,int ikincisayi) { return ilksayi+ikincisayi; } } class Log { public void LogAl() { System.out.println("Logaritma alyor..."); } } Uygulamann baarl bir ekilde derlendiini ve Log snf iin, otomatik olarak Log.class dosyasnn oluturulduunu grdm.

74

imdi ise, Uygulama.java dosyasnda, tanmlam olduum Log.class snfna ait bir nesne rnei oluturmak istiyorum. Bu amala Uygulama.java dosyasna aadaki kod satrlarn ekledim. Log l=new Log(); l.LogAl(); imdi uygulamay derlediimde ise, bir dizi hatalar serisi ile karlatm.

75

Aslnda derleme ileminin gereklemeyiinin sebebi gayet ak ve ortadayd. Eer bir snf tanmna herhangibir eriim belirteci eklemssek (public,private,friendly,protected) bu snf friendly olarak kabul edilmekte. Friendly olarak tanmlanm bir snfa ise sadece tanmlanm olduu paketten eriebiliriz. Bu nedenle Log snfn ayr bir snf dosyas halinde public olarak oluturmamz gerekir. Ayn Temel snfna yaptmz gibi. Kaynaklarmda eriim belirleyiciler ile ilgili pek ok aklama var ve bunun baka bir kahve molas olacan dnyorum. Bu nedenle u anki kahvemi paketler ile birlikte imeyi tercih ediyorum. Gelelim paketler arasnda ayn isimli snflarn nasl yorumlandklarna. Paketler ayn isimli snflar ierebilirler. Peki bu durumda bu snflar bir uygulama iinde nasl kullanabiliriz? Bunu renmek iin hemen kollar svadm ve path tanm aadaki gibi olan yeni bir paket tanmladm.

package com.bsenyurt.yazi; public class Temel { public void Uzunluk(String metin) { System.out.println(metin.length()); } } Yazm olduumuz bu snf, com.bsenyurt.yazi isimli pakete ait bir snf. Temel isimli snfmz, hem com.bsenyurt.yazi hemde com.bsenyurt.mat paketlerinde tanmlanm. Geri snflarn ierii tamamen farkl amalara hizmet ettiklerini gstermekte. imdi Uygulama.java isimli dosyamza bu iki paketide import edip, her iki paketten birer Temel snf nesnesi yaratmaya alalm.
76

import com.bsenyurt.mat.*; import com.bsenyurt.yazi.*; public class Uygulama { public static void main(String[] args) { Ussel u1=new Ussel(); double sonuc=u1.usal(2,4); System.out.println(sonuc); Temel t1=new Temel(); int toplam=t1.Toplama(12,15); System.out.println(toplam); Temel t2=new Temel(); t2.Uzunluk("Bu iin tkettiim kanc kahve..."); } } Elbette mantk olarak bu uygulamay daha derlemeden hatal olduunu syleyebiliriz. Hata udur. Derleyici hangi paketin Temel snfn kullanacan nereden bilecek? Dolaysyla bu kodlar derlemeye altmzda aadaki hata serileri ile yz yze gelmek zorunda kalrz.

77

zm ise gayet basit. Oluturulmak istenen nesne snf hangi paketin ierisinde yer alyorsa, o paket isminin yer ald bir notasyonu kullanmak. Aadaki rnek kodlarda olduu gibi. rnekte grld gibi, Temel snfnn hangi paketteki versiyonunu kullanmak istiyorsak tanmlamalar ona gre yapyoruz. Dikkat edilmesi gereken bir nokta daha vardr. Ka paket olursa olsun, ve bu paketler ayn isimde ka snf ierirse iersin, aadaki Temel snfna uygulanan teknik, tm snflar iin uygulanmal yani derleyciye bu snfn hangi paket iindeki snf olduu aka bildirilmelidir. import com.bsenyurt.mat.*; import com.bsenyurt.yazi.*; public class Uygulama { public static void main(String[] args) { Ussel u1=new Ussel(); double sonuc=u1.usal(2,4); System.out.println(sonuc); com.bsenyurt.mat.Temel t1=new com.bsenyurt.mat.Temel(); int toplam=t1.Toplama(12,15); System.out.println(toplam); com.bsenyurt.yazi.Temel t2=new com.bsenyurt.yazi.Temel(); t2.Uzunluk("Bu iin tkettiim kanc kahve..."); } } Son uygulamayda bitirdikten sonra bir baktm kafamda bir mrlt. JAR JAR aman JAR ne zaman...diyerek balayp giden bir melodiyi mrldanmaya baladm farkettim. Sanyorumki sonraki yudumumda JAR konusunu ilemem gerekiyor. JAR Java Arivi olarak tanmlayabileceim bir dosya format. Bu dosyann zellii, ierisinde eitli paketleri barndrabilmesi. Hatta, paketler dnda, kaynaklardan edindiim bilgiye gre, u
78

an iin sadece ne olduklarn bildiim ama nasl yapldklarn bilmediim appletler iin gerekli resim, ses dosyas gibi kaynaklarda bnyesinde barndrabiliyor. Paketleri bu ekilde bir yerde toplamann amacnn onlar bir arada dzenli bir ekilde tutmak olduunu syleyebiliriz. Ancak bununla birlikte, sktrma kabiliyeti sayesinde, zellikle internet zerinden gerekletirilen download ilemlerindede faydal olduunu syleyebiliriz. Dier yandan JAR dosyalarnn bence en nemli zellii, fiziki adres bamllndan kurtulmu olunmas. Bunun anlam u. u ana kadar yazm olduumuz paketleri belli klasrler ierisinde belirli bir sistematik ierisinde oluturduk. Ancak paketleri JAR dosyasna aldktan sonra, bu dosyay sistemde her hangibir klasre alabilir ve tek bir dosya iinden, tm paketlerimize kolayca ulaabiliriz. Ancak her zamanki gibi CLASSPATH ayarnda bu kez JAR dosyasnn konumunu belirtmeliyiz. Ne yazkki bunuda sylemek durumunda kaldm. Akas u CLASSPATHten kurtulamam olmak zc. Bu bilgiler nda hemen oluturduum iki paketi tek bir JAR dosyas ierisine almak iin giriimlerime baladm. Bunun iin paket tanmlarnn yer ald en st klasre kmam gerekiyor. Yani aadaki ekilde grld gibi JAR dosyasn oluturmak iin gerekli komutumu Paket isimli klasr iinden vereceim. Bylece, bu klasr altndaki tm paketleri JAR dosyas iine alm olacam.

te JAR dosyas iin kullandm komut.

79

Grld gibi JAR dosyas baarl bir ekilde oluturuldu. Burada jar komut dizimindeki -cf parametresi, izleyen parametredeki isimde(bs.jar) bir JAR dosyas yaratacamz ve bu dosya iine com dizini altndaki tm paketleri dahil edeceimizi belirtiyor. imdi JAR dosyasnn nne n katan ilevi gerekletirmek lazm. Bu dosyay buradan alyorum ve C: srcsnn hemen altndaki javap klasr altna tayorum. Hemen ardndan son yazm olduum uygulamay altryorum. Uygulama alyor almasnada u noktada paketlere nereden bakldndan emin deilim. Bir anda aklma CLASSPATH tanm geliyor. Hemen CLASSPATH tanmm yeniden ayarlyorum. Ancak bu kez bir klasrden ziyade JAR dosyasn bulunduu fiziki adres ile birlikte belirtiyorum.

80

Ltfen CLASSPATH tanmnn nasl yapldna dikkat edelim. nceki tanmlamalardan farkl olarak jar dosyasnn aka belirtiyoruz. imdi uygulamay tekrar altryorum ve baarl bir ekilde altn gryorum.

imdi aklma kurnazca bir fikir geliyor. Bu paketleri JAR dosyas iine almak ile acaba, bu paketleri sistemden kaldrdm zamanda uygulamam alcakm? Bu amala yola karak birazda sinsi bir glmseme ile, paketleri tanmlam olduum klasrleri sistemdeki baka bir yere tadm. Program tekrar altrdmda ise, aadaki hata mesaj ile karlatm.

81

Beklediim gibi olmad. Bir hata almamay dnyordum. Sanrm beklentim, paketleri JAR dosyas ierisine almak ile, onlar tm ierikleri ile birlikte buraya alabileceim ynndeydi. Ama blye olmad. Demekki JAR dosyalarn oluturmakla paketleri bir yerde topluyorduk ancak paketlerin adreslerini kesinlikle deitirmememiz veya silmememiz gerekiyordu. Bununla birlikte bu JAR dosyasnn fiziki olarak sistemden istediimiz yere tayabiliriz. Ama yinede CLASSPATH ayarlarn buna gre uyarlamamz gerekiyordu. Dier bir sorun ise uydu. Sonradan yazlm baka bir paketi bu JAR dosyasna nasl alabilirdik. Pekala JAR dosyasn tekrardan retebilirdik. Peki ya paketimiz baka bir klasrde yer alyorsa, bu paketi JAR dosyasna eklememiz ile, tek bir CLASSPATH tanm sayesinde, sistemdeki farkl klasrlerde yer alan paketlere eriebilirmiydik acaba? Gzel soru deil mi? Bunu renmenin tek bir yolu var. Java\Paket\ altndaki paket tanmlarndan farkl bir yerde bir paket oluturmak, bunu bs.jar dosyasna eklemek ve uygulama ierisinde bu yeni pakete erimeye almak.

Yeni klasr ierisinde hemen com.csharp.pk1 paketini oluturdum.

82

package com.csharp.pk1; public class Deneme { public void Yaz() { System.out.println("com.csharp.pk1 paketi burada..."); } } Java dosyasn baar ile derledikten sonra, sra bu paketi bs.jar dosyasna eklemeye geldi. Bunun iin aadaki komut dizimini kullandm.

Bu komut ile var olan JAR dosyamza yeni bir paket daha ekleyebiliriz. Aslnda -uf belirtilen dosyay gnceller. imdi jar dosyasnn ieriine baktmzda, com.csharp.pk1 paketinin konumununda eklendiini grrz.

83

imdi bu yeni paketimizde yazdmz metodumuzu uygulamamzda kullanalm. import com.bsenyurt.mat.*; import com.bsenyurt.yazi.*; import com.csharp.pk1.*; public class Uygulama { public static void main(String[] args) { Ussel u1=new Ussel(); double sonuc=u1.usal(2,4); System.out.println(sonuc); com.bsenyurt.mat.Temel t1=new com.bsenyurt.mat.Temel(); int toplam=t1.Toplama(12,15); System.out.println(toplam);

snfmza

ait

com.bsenyurt.yazi.Temel t2=new com.bsenyurt.yazi.Temel(); t2.Uzunluk("Bu iin tkettigim kainci kahve..."); Deneme d1=new Deneme(); d1.Yaz(); } } Uygulamay derlediimde, JAR dosyasna eklemi olduum yeni pakete ait snfnda baarl bir ekilde rneklendirildiini ve Yaz metodunun altrldn grdm.

84

Hay allah yine kahvem bitti. Artk paket kavramnda iyice iledikten sonra dinlenmenin zaman geldi. Bir sonraki kahve molasnda ise eriim belirtelerini incelersem Java iinde biraz daha yol katetmi olacam sanyorum. En azndan J harfinin apkasn izmi olabileceim.

Blm 6: Eriimleri Belirlemek (Access Specifiers ) Sanyorumki tm nesne ynelimli programlama dillerinde en nemli kavramlardan birisi, oluturulan nesnelerin birbirleri ile ilikilerinin ne lde olacana karar verilmesidir. Bu karar vermede, eriim belirleyicilerinin gerekten ok nemli bir yeri var. zellikle C# dili ile program yazarken, public, private gibi eriim belirleyicilerinin kullanmna zen gsteririm. Nitekim bunlar doru yerlerde doru amalar iin ve doru ynlendirmeler ile kullanmak isterim. Dier yandan, karmak ve kod satrlarnn says 10 binler ile ifade edilebilecek projelerde, kodu kitap okur gibi okuyabilmek, dilin temelinde yatan ancak ou zaman dikkat etmeden getiimiz unsurlarn iyi bilinmesini gerektirir. te benim inancma gre bu temellerden biriside eriim belirleyicileridir. Aslnda sz bu kadar uzatmann anlam yok. Hemen harekete gemeli ve icraatlar yapmalym diye dnyorum. Her nesne ynelimli programlama dili uygulaycsnn mutlaka ve mutlaka eriim belirleyicilerine ainal vardr. Hatta %100 olduundan eminim. Benim ainalm ise C# programlama dilinden geliyor. Bu hafta boyunca Java dilini renmek iin kendime ayrdm vakitlerde, eriim belirleyicileri ile ilgili olarak kaynaklar inceledim. Gerekten Java dilindede ok byk neme sahip olduklarn ve iyi bilinmeleri gerektiini kefetmi olduumu byk bir gururla sylemek isterim :) Java dilinde eriim belirleyicileri 4e ayrlmaktadr. Bunlar daha iyi anlayabilmek iin zel bir renklendirme stratejisi uyguladm aadaki tabloyu oluturdum.

85

Bu ekilde Java dilindeki eriim belirleyicilerini deiik renkler ile gstermeyi tercih ettim. Neden bu tarz bir renklendirme kullandm ise birazdan hep birlikte anlayacaz. Eriim belirleyicilerini snflara, metodlar ve alanlara uygulayabilmekteyiz. Elbette eriim belirleyicisinin tipine gre bir takm farkllklarnda olaca syleniyor. Anlalan bu farkllklar rnekleri yazdka daha iyi kavrayacam. Artk ie koyulmann tam sras. Scak bir fincan kahvemi yanma alyorum ve eriim belirleyicilerini tek tek incemeleye balyorum. ncelikle private eriim belirleyicisinden bahsedelim. Private isim anlam ilede zel bir kullanma sahiptir. Bu eriim belirleyicisi sadece metodlara ve alanlara uygulanabilir. Onu zel yapan, sadece tanmlanm olduu snf ierisinde kullanma izin vermesidir. Bu, baka bir paketten, varsaylan paketten hatta bu private yeleri ieren snfn bulunduu ayn paketteki dier snflardan bile eriimin gerekletirilemiyeceini anlatr. Anlatr anlatmasna ama, bunu rnekler ile incelemeden anlamak u an iin zor olabilir. Bu nedenle hemen bir rnek gelitirmeye karar verdim. Her zaman olduu gibi kodlar ileyebilmek ve eriim belirleyicilerinin paketler arasndaki etkileimini daha iyi anlayabilmek iin rnek bir paket hazrladm.

86

Bu kez com.bsenyurt.Ers isimli bir paketi kullanacam. lk rneimde, private alanlar ve metodlar ieren bir snfm var. package com.bsenyurt.Ers; public class PrivateD { private int Deger; private void Metod() { Deger=10; } } Bu paket ierisinde tanmladm PrivateD snf iinde Deger isimli bir private alan ve Metod isimli private bir yordam tanmladm. Private eriim belirleyicisinin uygulatt snrlamaya gre bu alan ve metoda sadece bu snf ierisinden eriebilirim. Nitekim, Deger alannn deerini Metod yordam iinden deitirebilmekteyim. Fakat private belirleyicisinin tanm gerei ncelikle bu paket iindeki snfa ati private yelere, bu paketi uygulayan baka bir snf iinden eriememem gerekiyor. Bunu ispat etmek zorunluluunu elbette hissediyorum. spat matematik bilmindede ok nemli bir yere sahip. Hatrlyorumda niversite yllarnda saysz ispat yapardk. Sonuta hipotezleri teoriye dntrr ve geerlilii kantlanrd. Ayn ey bence bir programlama dilini renirkende geerli. Verilen tanmlamalarn ispatn yapmay baarbilirsek o zaman dilde uzmanlamamz daha kolay ve gl olur. Sz uzatmadan private alanlarn bu tanm gerei ilk ispat yapmak zere bilgisayarmn herhangibir klasrnde bu paketi kullanacak bir snf daha yazdm. import com.bsenyurt.Ers.*; public class Sinif { void Yaz() { PrivateD n=new PrivateD();

87

System.out.println("PrivateD nesnesi oluturuldu"); System.out.println("Deger="+n.Deger); n.Metod(); System.out.println("Deger="+n.Deger); } } Bu snf iinde, com.bsenyurt.Ers paketi iindeki PrivateD snfnndan bir nesne rnei oluturmaya ve, PrivateD snf iindeki Deger alan ile Metod yordamlarn armaya altm. Sonu olarak, snf derlemeye altmda aadaki hatalar aldm.

spatn sadece ilk ksm bitti ama. Srada com.bsenyurt.Ers paketi iinde yer alan baka bir snf iinden, PrivateD snf iindeki private yelere eriebilip eriemiyeceimi kontrol etmem gerekiyor. Tanm gerei bu ekildede private yelere eriememem gerekli. Bu amala, com.bsenyurt.Ers paketi iinde baka bir snf tanmlyorum. package com.bsenyurt.Ers; public class PrivateD { private int Deger; private void Metod() { Deger=10; }

88

} class PSinif { void Deneme() { PrivateD pd=new PrivateD(); pd.Deger=50; pd.Metod(); } } Paketimin iinde PSinif isimli yeni bir snf tanmladm ve bu snf iindeki Deneme metodundan PrivateD snfndaki zel yelere erimeye altm. Sonu beklediim ve umduum gibi oldu.

Anlalan u ki private yelere, baka bir paketten yada ayn paket iinden eriemiyoruz. Bu da private yelerin sadece tanmlandklar snf iinden eriilebildikleri anlamna geliyor. Privatizim adn vereceim bir dogma burada kendini gsteriyor. Privatizim, aslnda nesne ynelimli programlama dillerinin, kapslleme kavramnn temelinde yatan uygulanabilirliin bir gstergesi. C# dilinde snf iindeki alanlar d ortamlardan soyutlamak istediimizde bunlar private tanmlar ve bu alanlara erimek iin zellikleri kullanrz. Ayn ekilde sadece snf iindeki zel alanlar ile ilgili ilemleri yapacak zel snflarda tanmlar ve bunlarda d ortamdan soyutlayarak kapsllemeyi gerekletiririz. Ayn dncelere java dili iinde geerli. Private kullanmna ilikin kaynak aratrmalarm incelerken gzel bir rnek yakaladm. Bu rnekte, bir snfa ait yapc
89

metod private olarak tanmlanmt. Bunun doal sonularn oturup bir ka saniye dndmde, bu yapcnn tanmland snfa ait bir nesne rneinin baka paketler iindeki snflar iinden yada ayn paketteki baka snflar iinden tanmlanamyacan farkettim. O halde bu tarz bir nesne rneini nasl oluturabilir ve alanlarna eriebilirdik. Hereyden te neden byle bir gereklilik olsun ki. Sebebi gayet basit. Bazen yapm olduumuz bir snfn kesinlikle baka snflar iinden rneklenememesini isteyebiliriz. Snfmz gerekten bal bana zeldir ve bu nedenle nesne rneinin oluturulabilmesi yasaklanmtr. Ancak bu snf iine koyacamz static bir metod bizim belirleyeceimiz kurallar erevesinde, bu nesne rneinin oluturulmasna ve kullanlmasna imkan salyabilir. Ne demek istediimi son paragraf tekrar okuduumda bende tam olarak kestiremedim. te keskinlii arttrmann yolu. Olay gereki bir rnek zerinde dnmek. Bu amala com.bsenyurt.Ers paketindeki PrivateD snfnn tanmn biraz deitirdim. ncelikle private yapc metodu tanmladm. package com.bsenyurt.Ers; public class PrivateD { private int Deger; private PrivateD() { } private void Metod() { Deger=10; } } class PSinif { void Deneme() {
90

} }

PrivateD pd=new PrivateD();

ncelikle grmek istediim, varsaylan yapcnn private tanmlanmasnn, nesne rneini oluturmaya olan etkisi idi. Etki aadaki gibi ekrana yansyverdi.

Peki o halde byle bir snf nasl rnekleyebilirdim. Cevap biraz dnnce ortaya kverdi. Static ve dardan eriilebilir bir metod iinde bu nesneyi tanmlayabilir ve snf ile ilgili gerekli, istediim dzenlemeleri bizzat snf yazan kii olarak ben yaptrtabilirdim. Bylece bu snfmn bakalar tarafndan ancak benim belirlediim kurallar erevesinde oluturulabilmesini salardm. Bu dncemin sonucunda aadaki rnek ortaya kverdi. package com.bsenyurt.Ers; public class PrivateD { private int Deger; private PrivateD() { } private void Yaz() { System.out.println(Deger); }

91

public static void Kullan() { PrivateD pd=new PrivateD(); pd.Deger=10; pd.Yaz(); } } imdi bu paketi baka bir snfta kullanmay denemem gerekiyor. Bu amalada aadaki rnei gelitirdim. import com.bsenyurt.Ers.*; public class Sinif { public static void main(String[] args) { PrivateD.Kullan(); } } Tabi burada gze arpan benim public eriim belirleyicisini daha anlatmadan kullanm olmam. Aslnda public eriim belirleyicisini dierlerini olduu gibi C# dilinden biliyorum. Bu nedenle static olarak tanmladm bu metoda dardaki bir snftan eriebilmem iin yani paket dndan halka ak ekilde tanmlamam gerekliydi. Ama yaznn ilerleyen ksmlarnda bu eriim belirleyicisinide detayl bir ekilde inceleyeceim. Ne de olsa gzden bir ey karmamak lazm. Uygulamay baarl bir ekilde derledikten sonra altrdm ve aadaki ekran grntsn elde ettim.

92

Private ile ilgili olarak sylenecek tek bir ey kald. Aslnda sylemekten ziyade ekil olarak private eriim belirleyicisinin nasl ilediini daha iyi grselleyebilmek. Bu amala nce kara kalemimi aldm ve kat zerinde bir izim yaptm. Kendimle mutabakata vardktan sonra ise, bu rnei dijital ortama geirdim. Sonuta aadaki grafik ortaya kt. Ha bu arada ilk ekilde private eriim belirleyicisini neden krmz renk ile gsterdiimi sanrm anlamsnzdr. Bu renk genelde eriimi kstlanm olan durumlar iin kullanlr. Ancak kastettiim elbetteki krmz trafik lambasda deil.

imdi sra geldi friendly eriim belirleyicisini incelemeye. Private eriim belirleyicisinden ziyade, friendly eriim belirleyicisi Java dilinde varsaylan eriim belirleyicisidir. Yani bir ye iin eriim belirleyicisi belirtilmesse bu ye dost canls olarak kabul edilir. Bununla birlikte friendly eriim belirleyicisi, alanlara, metodlara ve snflara uygulanabilir. zellii ise udur. Bu tipteki yelere ayn paket iinde eriilebilirken farkl paketlerden eriilememektedir. Elbette bu tanm ispat etmem gerekiyor. Haydi bakalm kollar svamann zaman geldi. Bir yudum kahve dopingi ve ardndan ite aadaki rnek. package com.bsenyurt.Ers;

93

class KardesSinif { int Deger; void Degistir(int yeniDeger) { Deger=yeniDeger; } } rnek snf yine com.bsenyurt.Ers paketi iinde oluturdum. Burada snf iin, int tipteki Deger deikeni iin ve Degistir isimli metod iin herhangibir eriim belirleyicisini kullanmadm. Bylece bu yelerin friendly eriim belirleyicisinine sahip olmasn salam oluyoruz. Tabi aklma saf ve yeni bir java programcs olarak, bu yelerin bana friendly anahtar kelimesini eklemekte gelmedi deil. Bunu yaptm zaman yani rnei aadaki ekilde deitirdiimde, java derleyicisi bana " Ben hereyin farkndaym, zaten bir ey yazmasan friendly olduklarn anlarm, beni bou bouna bir de bu yazdklarn denetlemek zorunda brakman anlamyorum" gibisinden bir hata mesaj verdi. friendly package com.bsenyurt.Ers; class KardesSinif { friendly int Deger; friendly void Degistir(int yeniDeger) { Deger=yeniDeger; } } Ve java derleyicisinin karlk olarak verdii tarihi cevap .

94

Boyumun lsn aldktan sonra rnei eski haline getirdim. Daha sonra sistemin her hangibir klasr iinde com.bsenyurt.Ers paketindeki KardesSinif snfn kullanacak bir rnek oluturdum. Teori eer doru ise, bu yeni rnek snf iinden, KardesSinifi yelerine eriememem gerekiyor. nk yeni rnek sistemin herhangibir yerinde varsaylan paket zellikleri ile oluturulacak. Bu amala aadaki rnei gelitirdim. import com.bsenyurt.Ers.*; class Kardes { public static void main(String[] args) { KardesSinif ks=new KardesSinif(); ks.Degistir(15); } } rnek elbette derlenmedi. Gerektende, com.bsenyurt.Ers paketi iindeki KardesSinifi snfn friendly olmas nedeni ile kullanamamtm.

95

Anlalan friendly eriim belirleyicisine sahip yeler aile dna kmay pek sevmiyorlar. Aileden kastm elbette bu yelerin bulunduu paket. Dolaysyla Teorinin ikinci ksmna bakmak gerekiyor. Buna gre, ayn paket iinden friendly yelere eriilebiliyor. Bu amala, com.bsenyurt.Ers paketi iinde aadaki snf oluturdum. Bu snf iinden aka, KardesSinif snfna erimeye allyor. KardesSinif snfndan ks isminde bir nesne rnei yaratlyor ve bu nesne zerinden Degistir isimli metod arlyor. package com.bsenyurt.Ers; public class Kardes { public void Kullan() { KardesSinif ks=new KardesSinif(); ks.Degistir(15); } } Bu kez derleme ilemi baarl bir ekilde gerekletirildi. Burada herhalde el alkanlndan olsa gerek, Kardes isimli snf tanmnn bana ve Kullan isimli metodun bana public eriim belirleyicisini ekledim. Evet aslnda public ile ilgili teorileri C#
96

tan bilmeme ramen, Javada nasl olduunu merak ediyorum. Ancak hereyden nce, friendly ile ilgili son bir ey yapmam gerekiyor. Friendly eriim belirleyicisinin tanmn ekillendirmek.

Private ve friendly eriim belirleyicilerinin kstlamalarndan sonra yle kendimi zgr hissettirecek bir eriim belirleyicisine ihtiyacm olduunu dnmeye baladm. Bu arzumun karl sanyorumki public eriim belirleyicisi. Public eriim belirleyicisine sahip snflar, metodlar ve alanlara, herhangibir paketten, ayn paketten, varsaylan paketten ksaca heryerden eriilebilir. Bu kulaa ho gelen bir tanm olmakla birlikte, bazen programclarn ar bedeller demesinede neden olmutur. Bir yeyi herkese amak gzel bir fikir gibi grnebilir. Ancak burada durum, Linux gibi ak kaynakl bir iletim sisteminin geliiminden ok daha farkldr. ou zaman i uygulamalarnda snflarn belli bal yelerini hatta snflarn kendilerini d dnyaya kapatmak ve denetimi, kontrol tamamen ele almak isteriz. Bazen sadece belli bal yelerin herkese ak olmasn isteriz. rnein bir bankaclk uygulamas iin, banka mterilerinin birer snf rnei olarak temsil edildiklerini dndmzde, sadece yetkili personelin bu kiiye ait bilgileri grmesi gerekecektir. Hatta mterinin kendisi bile snf tanm iindeki, hesap no yada bakiye gibi
97

bilgilere ulamak iin, ifre ve daha fazlasna demek zorundadr. te bu gibi bir i uygulamas yelerin son derece iyi planlanmasn gerektirir. Bir mteri snfn herkese kapatabilirsin. Ancak, bu snf iindelki zel bilgileri private yapmak, bu snfn yer ald paketler zerinde alan programclarn kullanabilmesi iin friendly yeler amak ve ifre sorgulama yada kullanc dorulama gibi ilemleri herkesin kullanmna aan public metodlar uygulatmak daha mantkldr. O nedenle public hem iyidir hemde iyi deildir. Bu nedenle her zaman inandm bir ey vardr. Bir uygulama nesne ynelimli programlama dilleri zerinde koacaksa, onu koturmadan nce gerekten iyi tasarlanmaldr. Yaplan herey, belkide 3 kez kendimize sorulup, 3 kez program ekibine sorulup ve kezde genel mdre sorulup ondan sonra yrrle girmelidir. Evet 3 kez sormak biraz abart gelebilir ancak 3 gvenlik grevlisinin, genel mdrn, program ekibinin ve hatta saysz 3n bir araya gelerek oluturduu kalabalk bir mteri grubunun bizi kovalamasndan iyidir. Neyse bu kadar abart senaryolar gzmz korkutmamal deil mi? Sonu olarak Javay bu kahve molasnda ilerletmek zorunluluunu hissediyorum. O halde beklemenin anlam yok. Srada public eriim belirleyicisi var. Aslnda public eriim belirleyicisi ile ilgili sylenecek fazla bir ey yok. Bu eriim belirleyicisini incelemek iin com.bsenyurt.Ers paketi iine aadaki snf ekledim. package com.bsenyurt.Ers; public class Topla { public int Toplam(int d1, int d2) { return d1+d2; } } public int Eleman=10;

98

imdi ilk denemek istediim bu snf iindeki public yelere ayn paket iinden eriip eriemiyeceim. Bu amala, com.bsenyurt.Ers paketi iinde yer alan bir snf aadaki ekilde dzenledim. package com.bsenyurt.Ers; public class PSinif { public void ToplamAl() { Topla t=new Topla(); int t1=t.Toplam(10,11); int t2=t.Toplam(12,12); int t3=t.eleman; t.eleman=1; } } PSinif snf iinden, ayn pakette yer alan, Topla isimli snfn, public yelerine erimeye altm. Bu snf derlediimde herhangibir hata mesaj almaym, bu eriimin geerli olduunu gstermekteydi. Srada, bu public yelere baka bir paket ierisinden eriip eriemiyeceimin ispat var. Bunun iin, com.bsenyurt.Yazi paketi iindeki Temel snfn kullandm. Bu snfn kodlarna, com.bsenyurt.Ers.PSinif snfndaki ToplamAl metodunun aynsn ekledim. package com.bsenyurt.yazi; import com.bsenyurt.Ers.Topla; public class Temel { public void Uzunluk(String metin) { System.out.println(metin.length()); } public void ToplamAl() {

99

Topla t=new Topla(); int t1=t.Toplam(10,11); int t2=t.Toplam(12,12); int t3=t.eleman; t.eleman=1; } }

Sonuta, bu snfta baarl bir ekilde derlendi. Yani, public yelere, baka bir paket iindende eriebilmitik. Aadaki ekil sanyorumki Public eriim belirleyicisinin davrann ok daha net aklyor.

Eriim belirleyicilerinde son olarak protected eriim belirleyicisi kald. Bu eriim belirleyicisi aslnda kaltm kavram ile ilikili. Hazr kaltm demiken bir sonraki kahve molasnda bu konuyu ilemeye alacam. te o zaman, protected eriim belirleyicisinin ilevini daha iyi anlayabileceimi sanyorum. Kahvemden son bir yudum aldmda aklma, eriim belirleyicilerinin etki alanlarn gsteren bir tablo yapmak geldi. Bunun iin bir sre uramam gerekti ama sonunda baardm. Bu tablo eriim belirleyicilerinin etki alanlarn tam olarak aklayabiliyor. Bu tablo ayn zamanda, buraya kadar ilediklerimin zetlenmesindede bana olduka yardmc oldu.

100

Ayn Farkl Tr. Paket Paket Paket Snf public friendly public Metod private friendly protected public Alan private friendly protected Bu tablo eriim belirleyicilerinin etki alanlarn kolayca anlamama yarad. Krmzlar eriimin olmadn, yeiller ise eriim olduunu gsteriyor elbette. Tablonun okunmas ise son derece kolay. rnein, Snflar ele alalm. Snflarda dikkat edilmesi gereken nokta, protected yada private snflarn tanmlanamad. Dier yandan public bir snfa her yerden eriebiliyoruz. Ayn paket iinden, farkl bir paket iinden, hatta tretilmi bir paket iindende. Lakin friendly olarak yani dost canls bir snf bildirdiimizde bu snfa sadece ayn paket iinden eriilebilmekte. Bu okuma ekli alanlar ve metodlar iinde geerli.

Blm 7: Kaltm ( Inheritance ) te nesne ynelimli programlama dillerinin en nemli kavramlarndan birisi. Kaltm. Normalde bu kavram herkes gerek hayattan biliyor. En basit anlamda, rnein ben, annemin gzlerini almm dediimde, tp uzmanlarnn buna getirdikleri yorum " siz annenizden kaltmsal olarak u zelikleri almsnz" oluyor. Programlama dillerinde de kaltmn rolnn ayn olduunu syliyebilirim. Zaten nesne ynelimli
101

programlama dillerini tasarlayan uzmanlar, gerek hayat problemlerini, bilgisayar ortamna tayabilmek amacyla en etkili modelleri gelitirmiler. te bu model ierisine kaltmda katarak ok nemli bir zelliin kullanlabilmesini salamlar. Her ey iyi gzel de bu kaltm kavramnn programlama dilleri ierisinde bir tanmn yapmak lazm. En genel tanm ile kaltm, "bir snftan yeni snflar tretmektir" diyebilirim. Bu genel kavramn arkasnda elbette pek ok ey sylenebilir. Hereyden nce kaltm yolu ile bir snftan, yeni snflar tretilebilmesinin, tretilen snflara etkisi nedir? Bu sorunun cevab kaltmnda zn oluturmaktadr. Tretilen her bir snf, tredii snfn zelliklerinide devralr. Buradan, tretilmi bir snf ierisinden, tredii snfa ait yelere eriilebilecei sonucunu kartabiliriz. Elbette bu eriiminde baz kurallar vardr. rnein eriim belirleyicilerinin etkisi veya ayn yelerin kullanl gibi durumlar. Bu temel bilgiler nda ncelikle ie basit bir kaltm senaryosu ile balamam gerektiini dnyorum. Neden bir snftan baka snflar tretiriz ki? Bunun cevab son derece gzel. Tm snflarda ortak olan zellikleri tek bir snf ierisinde toparlamak. Bu modellerimizi gelitirirken, her snf iin ortak olan yelerin tekrar yazlmasn engellemekle kalmyacak, snflar arasnda dzenli bir hiyerari yapsnn olumasnda salayacak. imdi gzel bir rnek lazm bana. Gerek hayat modelleri bu i iin biilmi kaftan. rnein, otomobilleri bir temel snf olarak dnebiliriz. Bu snftan otomobillere ait deiik kategorileri tretebiliriz.

102

te basit bir rnek. Buradaki tm snflarn ortak bir takm zellikleri var. Bir motorlarnn olmas, tekerleklerinin olmas, viteslerinin olmas vb. Ama ayn zamanda her ayr snfn kendine has zellikleride var. rnein ralli aralar iin gvenlik bariyerlerinin olmas, pilotlar iin kasklarn kullanlmas gibi. Bu tabloyu inceleyince, her ralli arac bir otomobildir diyebiliriz. Bu ralli aralarnn otomobil snfndan trediini gsterir. Dier yandan her wrc bir ralli aracdr da diyebiliriz. Bu ise, wrc aralarnn ralli aralarnn bir takm ortak zelliklerine sahip olduunu ayrca otomobillerinde bir takm ortak zelliklerine sahip olduunu gsterir. lk aamada, Ralli, Ticari, zel ve Spor snflarnn Otomobil snfndan trediini syleyebiliriz. Bununla birlikte WRC ve GrupN snflarda Otomobil snfndan treyen Ralli snfndan tremitir. Yani burada unu syleyebilmek mmkndr. WRC snf hem Ralli snfnn hemde Otomobil snfnn zelliklerine kaltmsal olarak sahiptir. Otomobil snf dnda baka rneklerde verebiliriz. rnein, deerli dostum Sefer Algann Her Ynyle C# isimli kitabnda kaltm iin verdii Memeli hayvanlar rnei gibi.

103

ki snf arasnda kaltm zelliinin olduunu anlayabilmek iin is-a ad verilen bir ilikinin kullanldn farkettim. Yani, the cat is a mammiferous. Kedi bir memelidir. Bu ilikiyi yakaldysak ite o zaman kaltmdan sz edebiliyoruz. Yukardaki rnekte olduu gibi. Gelelim kaltmn java snflarnda nasl uygulandna. Bu amala hemen bir snf oluturuyorum. Konu kaltm olduu iin aklma hemen sevgili Temel geliyor. Beni her zaman neelendiren Karadenizli Temel. Kaltmn nasl uygulandn grmek iin Temel isimli ana snf bence biilmi kaftan. Deerli Temel aslnda burada bizim iin nemli bir tanmn temelini oluturuyor ayn zamanda. Kaltm senaryolarnda, tretmenin yapld en st snflar Temel Snf(base class), bu snftan tretilen snflarda Tureyen Snf( derived class) olarak adlandrlyor. Bu ksa bilginin ardndan hemen kodlarm yazmaya baladm. class Temel { public void Kimim() { System.out.println("Ben Temelim"); } } Hemen ardndan bu snftan baka bir snf tretiyorum .

104

class Tureyen extends Temel { public void Ben() { System.out.println("Ben Treyenim"); } } Tretme ii java programlama dilinde extends anahtar szc ile yaplyor. Aslnda C# dilinde bu tanmlamay yapmak daha kolay. ki nokta st ste iareti ile :) imdide bu snflar uygulama iinden bir kullanmak lazm. lk olarak merak ettiim konu Tureyen snfa ait bir nesne zerinden, temel snftaki bir yeye eriip eriemiyeceim. public class Program { public static void main(String[] args) { Tureyen turemis=new Tureyen(); turemis.Kimim(); } } Bu amala Tureyen snfa ait bir nesne rnei oluturdum ve bu nesne rnei zerinden Temel snf iinde yer alan Kimim isimli metoda erimeye altm. te sonu.

te kaltmn doal sonucu olarak, temel bir snftan tretilmi bir nesne zerinden, temel snftaki ortak metoda erime imkanna sahip oldum. Bu noktada aklma object snf geliverdi. C# programlama dilinden biliyordumki, Object snf en tepedeki snft ve dier tm snflarn atasyd. Acaba java dilindede bu
105

bylemiydi? Bunu grmenin en kolay yolu object snfna ait toString metodunu herhangibir snfa uygulamakt. Bu amala tremi snf ierisinde toString metodunu kullanmay denedim. class Temel { public void Kimim() { System.out.println("Ben Temelim"); } } class Tureyen extends Temel { public void Ben() { Integer agirlik=new Integer(125); System.out.println("Ben Treyenim"); System.out.println("Agirlik "+agirlik.toString()); } } public class Program { public static void main(String[] args) { Tureyen turemis=new Tureyen(); turemis.Ben(); } } Uygulamada, yeni bir integer deiken tanmlayp bu deiken zerinden object snfnn toString metodunu altrdm. toString metodu, saysal deeri string trne dntrmekteydi. Uygulamay altrdmda aadaki sonucu elde ettim.

106

Programn almasnda zel veya deiik bir sonu yoktu. Ancak nemli olan, bir snf nesnesinden object snfnn metodlarna eriebilmi olmamd. Kaynaklardan edindiim bilgiye gre buna gizli tretme ismi veriliyor. Bu, oluturulan her snfn object snfndan gizlice tretildii ve bu nedenlede object snfna ait temel metodlara ulalabildiini ifade etmekte. Elbette bu Object snfndaki yelerin, bu snftan treyen her snf iin kullanlabilirliini aklyordu. Bu konu ile ilgili olarak, gzel bir kaynakta aadaki resmi elde ettim. Buna gre object snf javadaki tm snflarn atasyd. Sayg duyulmas gereken bir snf olarak, hiyerarinin en tepesinde yer almaktayd.

107

rnein, ComponentEvent snf, WindowEvent snfndan, WindowEvent snf, AWTEvent snfndan, AWTEvent snf EventObject snfndan ve son olarakta EventObject snfda Object snfndan tretilmilerdi. Bu noktada aklma byle bir hiyeraride ComponentEvent snfnn Object snfndan itibaren nasl tretildii geldi. Acaba bir snf birden fazla snftan tretilebilirmiydi? Nitekim yukardaki ekli hiyerarik yaps ile gz nne almadm zaman byle bir sonu ortaya kyordu. Bunu anlamn en gzel yolu, bir snf bir ka snftan tretmeye almakt. Bu amala aadaki gibi bir bildirim denedim.
108

class Alt extends Temel,Tureyen { }

Aldm hata mesaj tam olarak aklayc deildi aslnda. Ancak derleyici virgl yerine { kme parantezini bekliyordu. Bu aslnda bir ipucuydu. nk virgl yerine kme parantezinin istenmesi, bu noktadan itibaren direkt olarak snf blou istendiini gsteriyordu. Dolaysyla virgl notasyonu bir ie yaramamt. Ancak dier taraftan, dayanamayp kaynaklara baktmda, java dilindede, C# dilinde olduu gibi snflar aras oklu kaltmn desteklenmediini rendim. Tahmin ettiim gibi, oklu kaltm uygulayabilmek amacyla arayzler(Interfaces) kullanlacakt. Kaltm ile ilgili bir dier nemli konu ise yapc metodlarn bu iteki paylaryd. Bir kaltm hiyerarisi ierisinde acaba en alttaki snfa ait bir nesnenin oluturulmasnn, bu snfn tredii snflarn yapclar zerinde ne gibi bir etkisi olabilirdi? Bunu grmek iin, aadaki gibi bir uygulama gelitirdim. Bu kez alt alta snf trettim. Her bir snfn varsaylan yapclarn dzenledim. class Grafik { public Grafik() { System.out.println("Grafik SINIFI YAPICISI"); } } class Daire extends Grafik { public Daire()
109

{ }

System.out.println("Daire SINIFI YAPICISI");

} class Elips extends Daire { public Elips() { System.out.println("Elips SINIFI YAPICISI"); } } public class Program { public static void main(String[] args) { Elips e=new Elips(); } } rnein hiyerarisini daha iyi kavrayabilmek amacyla kat kalemi alp aadaki gibi grafikletirmeyide ihmal etmedim. Burada Elips snf hiyerarinin el altndaki snftr. Grafik snf ise en stteki snftr. Uygulamay altrdmda, yapc metodlarn bu hiyerarik yapya uygun bir biimde altrldn grdm. Yani Elips snfndan bir nesne trettiimde, java derleyicisi, bu snfn yer ald hiyerarideki en st snfa kadar kt ve ilk olarak bu en stteki snfn yani Grafik snfnn yapcsn ard. Bu bana, tretilmi bir nesne yaratldnda, tretilmi snflar iin ortak olan zelliklerin, temel snf yapcs ierisinden balang ayarlarna getirilebileceini gsterdi. Bylece her tremi nesne sayesinde, temel snftaki ortak alanlarn deerlerinide nesne oluturulurken ayarlayabilirdik.

110

Varsaylan yapclar iin geerli olan bu durum acaba, parametre alan yapclar iin nasl ileyecekti? Hiyeraride st snflara kldka, en st snftan aaya doru tm yapclarn mutlaka alaca kesindi. Peki deeleri nasl aktaracatk. Daha net dndmde, C# dilinde yapclar iin kullandm base anahtar szcnn yerini java dilinde ne alcakt? Kaynak aratrmalarm, bunun iin super bir anahtar szcn olduunu gsterdi. Super ismindeki bu anahtar szck kullanm ekli itibariyle, base anahtar szcnn ilkel haliymi diyebilirim. Bu durumu incelemek amacyla aadaki gibi rnek oluturdum. Burada Grafik snf temel snf olarak, Taban ve Yukselik isminde double tipinden deikenlere sahip. Yapc metodunu ise bu alanlarn deerlerini belirlemek zere ayarladm. imdi gelelim Ucgen snfna. Bu snfta, Grafik snfndan tretiliyor. Yapc metodu parametre almakta. lk iki parametre, temel snf olan Grafik snfndaki yapclar vastasyla ayarlanabilir. te bu amala super anahtar kelimesini kullanarak bu iki parametreyi bir stteki snfn yapc metoduna gnderiyorum. Bu benim ne iime yarad peki? Uygulamada Ucgen snfndan bir nesneyi 3 parametre alan yapc metodu ile oluturduumda, ilk iki parametre, temel snftaki yapcya aktarlyor ve bylece benim Grafik snfndan trettiim nesnelerin ortak zellikleri olan Taban ve Ykseklii, treyen snf iinden tekrar bildirmek zorunda kalmyorum. class Grafik { double Taban; double Yukseklik; public Grafik(double a,double b) {
111

Taban=a; Yukseklik=b; } } class Ucgen extends Grafik { String UcgenTuru; public Ucgen(double yc,double yuk,String tip) { super(yc,yuk); UcgenTuru=tip; } public double Alan() { return (Taban*Yukseklik)/2; } } public class Program { public static void main(String[] args) { Ucgen u=new Ucgen(10,20,"Eskenar"); System.out.println("Ucgen alani "+u.Alan()); } } rnei altrdmda aadaki ekran grntsn elde ettim.

Yapc metodlar arasndaki parametre aktarm ile ilgili kafama taklan nokta, super teknii ile acaba hiyerarinin en tepesindeki yapcyam gidiliyor sorusuydu. C# dilinde base anahtar kelimesi, bir stteki snfn yapclarna gnderme yapyordu. Bu durum java dilindede byle olmalyd. Hemen bir
112

deneme uygulamas yazarak konuyu akla kavuturmaya altm. class Tepedeki { int ADegeri; int BDegeri; public Tepedeki(int a,int b) { ADegeri=a; BDegeri=b; } } class OrtaKat extends Tepedeki { String Tanim; public OrtaKat(int a,int b,String t) { super(a,b); Tanim=t; } } class Bodrum extends OrtaKat { public Bodrum(int ad,int bd,String ta) { super(ad,bd,ta); } public void Yaz() { System.out.println(ADegeri+" "+BDegeri+" "+Tanim); } } public class Program { public static void main(String[] args) { Bodrum b=new Bodrum(10,4,"Apratman"); b.Yaz();

113

rnekte Bodrum snfnn yapcsnda kullandm super anahtar szc ile bir st snftaki yani OrtaKat snfndaki yapcya parametreyide aktarm oldum. OrtaKat snfndaki yapc ise gelen parametrelerden ilk ikisini Tepedeki snfnn yapcsna aktard. Aslnda bu durumu aadaki gibi ekilledirmek anlamak asndan daha kolay olucak.

En alttaki snf yapcsndan, en stteki snf yapcsna kadar super tekniini kullanarak klabilmekteydi. Ancak nemli olan nokta, super tekniinin, C# dilindeki base anahtar szcnde olduu gibi, tretilen snfn bir stndeki snfa gndermeler yaptyd. Java dilide C# dili gibi kesin askeri kurallar zerine kurulmu bir dil. Bu kanya nerden mi vardm? Yukardaki rnekte aadaki gibi bir deiiklik yaptm. class Bodrum extends OrtaKat { public Bodrum(int ad,int bd,String ta)

114

System.out.println("superden onceki satir"); super(ad,bd,ta); } public void Yaz() { System.out.println(ADegeri+" "+BDegeri+" "+Tanim); } } Tek yaptm super anahtar szcnn kullanmndan nce basit bir kod satr eklemekti. Ancak sonuta aadaki hata mesajn aldm. Super, yapc metod ierisinde mutlaka ilk satrda kullanlmalyd.

Kaltm ile ilgili bir dier nemli konu ise, C# dilinden isim gizleme (name hidding) olarak bildiim konunun nasl ele alndyd. C# dilinde, treyen snf ve temel snflarda ayn yeleri tanmladmzda, treyen snftaki yenin, temel snftaki yeyi gizlediini biliyordum. Bu durumun Java dilinde nasl oldunu grmek iin tek yapmam gereken, temel ve treyen snflarda ayn yeleri kullanp, treyen snf nesnesi zerinden bu yeye erimeye almakt. Bu amala aadaki nemsiz, herhangibir ie yaramayan ama bana isim gizlemenin nasl olduunu gsterecek kodlar yazdm. class Temel { public void Metod1() {
115

} }

System.out.println("Temel snftan Metod1");

class Tureyen extends Temel { public void Metod1() { System.out.println("Tureyen snftan Metod1"); } } public class Program2 { public static void main(String[] args) { Tureyen t=new Tureyen(); t.Metod1(); } } Bu uygulamay derleyip altrdmda aadaki sonucu elde ettim.

C# dilindeki gibi olmu ve treyen snftaki metod temel snftakini gizlemiti. Ancak arada belirgin bir fark vard. C# dilinde, derleyici kullancy metod gizlemeye alt ynnde uyarr ve new operatrn kullanmamz ister. Bu ayn zamanda, treyen snftaki yenin, temel snfta ayn isimli baka bir yeyide gizlediini aka belirtir. Elbetteki bunun bize salad katk kodun kolay okunabilirlii ve treyen snftaki hangi yelerin temel snf ierisinde aynen yer aldnn bilinmesidir. Bu bana kalrsa Java dilindeki bir eksiklik. C#

116

dilinde bu eksiklik giderilmi ve new anahtar szc iin iine katlm ki buda bir gerek. Java dilinde temel snf yelerinin, treyen snfta yeniden bildirilmesi override olarak adlandrlyor. Yani temel snftaki metod treyen snfta geersiz hale geliyor. Ancak kaynaklardan edindiim bilgiye gre, bu yelerin eriim belirleyicilerinin byk bir nemi var. yleki; aadaki rnei uygulamaya altmda, class Temel { protected void Metod1() { System.out.println("Temel snftan Metod1"); } } class Tureyen extends Temel { private void Metod1() { System.out.println("Tureyen snftan Metod1"); } } public class Program2 { public static void main(String[] args) { Tureyen tureyen=new Tureyen(); tureyen.Metod1(); } } aadaki hata mesaj ile karlaverdim.

117

Buradan u sonu kyordu. Treyen snfta geersiz hale getirilen metod, temel snftaki metodlar ile ya ayn eriim belirleyicisine sahip olmal yada daha eriilebilir bir eriim belirleyicisi kullanlmalyd. Biraz dndmde olayn ciddiyetine vardm. Eriim sznn bir cmlede bu kadar ok kullanlmas biraz sonra kavramsal adan kafada bulanklk yapcak eyler aklanmas anlamna geliyordu. Gerektende eer treyen snftaki metodu protected veya public yaparsak (ki burada public "daha eriilebilir" manasna geliyormu) o zaman kodumuz sorunsuz ekilde alacakt. Eriim belirleyicilerinin temel snf ve treyen snf arasnda oynad rol anlatabilmek iin yaplabilecek en gzel ey bu ilemi kafada ekillendirmek ve grafie dkmekti.

ekildeki okun aaya doru inmesinin sebebi, eriim belirleyicileri arasndaki eriilebilirlik snrlarnn durumudur. Public en st mertebeden bir eriim belirleyicisi olarak her kes tarafnda eriilebilirken, en altta yer alan private eriim belirleyicisi en dk rtbeli eriim belirleyicisidir.

118

Bu ekile gre dnldnde unu syleyebilirim artk. Temel snfta friendly eriim belirleyicisine sahip olan bir ye, treyen snfta ya friendly olmaldr yada protected veya public olmaldr. Denemesi bedava deyip kollar svadm. Temel snftaki metodu friendly yaptm ve ilk olarak treyen snfta ayn eriim belirleyicisini kullandm. Tabi hemen klasik olarak bir dili yeni renmeye balayan birisi gibi hataya dtm ve metodlarn bana hemen friendly eriim belirleyicisini yazverdim. Her eyi aka belirtecem ya...Oysaki yazmamam zaten bu anlama geliyordu ve Java derleyicim beni uyararak hatamn farkna varmam salad. class Temel { void Metod1() { System.out.println("Temel snftan Metod1"); } } class Tureyen extends Temel { void Metod1() { System.out.println("Tureyen snftan Metod1"); } } Kod sorunsuz bir ekilde almt. imdi ise, treyen snftaki metodu friendly eriiminden daha st kademede olan protected yaptm. class Temel { void Metod1() { System.out.println("Temel snftan Metod1"); } }

119

class Tureyen extends Temel { protected void Metod1() { System.out.println("Tureyen snftan Metod1"); } } Kod yine sorunsuz bir ekilde alt. Srada treyen snftaki metodu en st seviyede eriilebilirlik salyan public yapmak kalmt. class Temel { void Metod1() { System.out.println("Temel snftan Metod1"); } } class Tureyen extends Temel { public void Metod1() { System.out.println("Tureyen snftan Metod1"); } } ok gzel. Bu seferde kod alt. imdide durumu ispatlamam tamamlayacak anti tezi uygulamam gerekiyordu. Yani, treyen snftaki metodu, temel snftakinden daha dk seviyeli bir eriim belirleyici ile (bu durumda bir tek private kalyor) kullanmaya almak. class Temel { void Metod1() { System.out.println("Temel snftan Metod1"); }
120

} class Tureyen extends Temel { private void Metod1() { System.out.println("Tureyen snftan Metod1"); } } Ta taaaa.... Beklediim hata gereklemiti.

Kaltm ile ilgili temeller bitmek bilmiyordu. Kaynaklar kartrdka debileceim baka tuzaklarda karma kyordu. Bunlardan bir tanesi farkl paketler ierisinde yer alan snflar aras kaltm sz konusu olduunda, treyen snftaki yelerin geersiz klnmas srasnda olabilecek olaylard. Asl tuzak soru uydu; Temel snfta friendly olarak tanmlanm bir ye, baka bir pakette bu snftan treyen bir snf iinde geersiz klnrmyd? Denemesi bedeva deyip denemektense, nce akl muhakemesi yaparak konuya yaklatm ve bir karara vardm. Friendly eriim belirleyicisi bir yeye sadece bulunduu paket iinden eriim hakk veriyordu. Dolaysyla baka bir pakette, tretilen bir snf iinde bu ye geersiz klnamazd. Hereyden nce, treyen snf, temel snfn bulunduu paketteki friendly eriim belirleyicilerinden haberdar deildi ve bu aslnda durumu aklyordu. Treyen snftaki metod, tredii snftaki metodtan haberdar deil ise onu nasl geersiz klabilirdiki. Bu varsaym nda, bir rnek ile konuyu derinlemesine incelemeye karar verdim. Yapmam gereklen bir paket ierisinde
121

yer alan bir snftaki friendly metodu, baka bir pakette bu snftan treyen bir snf iinde geersiz klmaya almakt. nce temel snfn bulunduu paketi yazdm. package com.bsenyurt.mat; public class Temel { void Metod1() { System.out.println("Temel snftan Metod1"); } public int Toplama(int ilksayi,int ikincisayi) { return ilksayi+ikincisayi; } } imdi farkl bir pakette, Temel snfndan baka bir snf tretecek ve Metod1i buradada kullanacaktm. package com.bsenyurt.yazi; import com.bsenyurt.mat.*; public class Tureyen extends Temel { public void Metod1() { System.out.println("Tureyen snftan Metod1"); } public static void main(String[] args) { Tureyen t=new Tureyen(); t.Metod1(); } } Uygulama sylendii sorunsuz ekilde alt. Ancak kaynaklarda gibi, tureyen snfn temel snftaki Metod1in

122

varlndan haberdar olmadn nasl grebilirdim. Sorun buradayd. Eer bunu baarabilirsem, zaten treyen snftaki Metod1 in kendi bana bir metod olduunu yani aslnda temel snftaki metodu geersiz klmadn syliyebilirdim. Bu ii iki satrlk kod paras zd. Temel snftan bir nesne tretilecek ve bu nesne zerinden Metod1 arlacakt. Temel temel=new Temel(); temel.Metod1();

Gerektende kaynaklarda sylendii gibi olmutu. Temel snftan bir nesne oluturabilmitim fakat Metod1e friendly olduu iin eriememitim. Dahas bu, treyen snfn Temel snftaki metotdan haberdar olmad anlamna gelmekteydi. imdi ise kaltm ile ilgili olarak aklma taklan baka bir konu vard. Bu c# dilinde ska yaplan ve sanal metodlarn kullanmn douran bir testtir. Acaba treyen snf trden bir nesneyi bir temel snf nesnesine aktarsak ve ardndan, temel snf nesnesi zerinden, treyen snftaki bir yeye ulamaya alsak ne olurdu? C# dilinde bu, derleyicinin hata vermesine neden olmaktayd. nk temel snf treyen snf yeleri hakknda herhangibir bilgiye sahip olamazd. Ancak sanal metod tanmalamalar ile, temel snf nesnesi zerinden treyen snftaki bir yeye erimek mmkn olabiliyordu. Yani temel snftaki sanal metod treyen snfta geersiz klnyordu (override). Acaba java dilinde durum nasld? Bunu renmenin yolu her zamanki gibi iyi bir testten geiyordu. class Temel { public void Metod1()

123

{ } }

System.out.println("Temel snftan Metod1");

class Tureyen extends Temel { public void Metod1() { System.out.println("Tureyen snftan Metod1"); } public void Metod2() { System.out.println("Tureyen snftan Metod2"); } } public class Program2 { public static void main(String[] args) { Tureyen tureyen=new Tureyen(); Temel temel=new Temel(); temel=tureyen; temel.Metod2(); } }

Beklediim gibi bir sonu. Her ne kadar derleyici hatas bana fazla anlaml gelmesede, Temel snf nesnesi zerinden treyen

124

snftaki yeye eriememitim. Peki ya acaba Javada bana bu imkan verecek C# taki sanal metodlar gibi unsurlar varmyd? Java dilini renmeye baladmda bana bu konu ile ilgili pek ok kaynak gerekmiti. Yakn bir arkdam bu konuda bana yardmc oldu ve KaZaAraaa (bilmeden, istemeden, anszn karmza kan) bir ka e-book getirdi. Bu kitaplardan virtual anahtar szcn arattmda, sadece JVM (Java Virtual Machine) konularna ulatm. Amacm C# taki virtual metodlar Java dilinde bulabilmekti. Ancak henz bu muradma eriemedim. Belkide ve byk olsallkla Java dilinde, virtual metodlar yerine baka elemanlar kullanlyor olabilirdi. Kim bilir ilerleyen zamanlarda karma kar umarm. Belki bir sonraki hafta youn ekilde inceleyeceim ok biimlilik (polimorphsym) konusunda.

Blm 8: Final Yoksa sonuna m geldim? Olurmu hi yle ey canm, daha dnya kadar yolum var. Kaynaklarmdan Java dilini renmeye alrken, final anahtar szcnden bahseden yerlere rastladmda, java dilini daha balarda bitirmek isteyeceklerini dnmemitim zaten. ou kaynakta araya sktrlmt bu kavram ancak saladklar ile bence renilmesi gereken niteliklerden birisiydi. Hereyden nce mkemmelliin ayrntlarda gizli olduunu biliyordum. Gerektende ou kaynak final kavramna sadece yorum satrlar ile deinmi olsada, ierik asndan ayrca incelenmeyi gerektiriyordu. Aslnda buna deerdide. Sz gelimi, geen hafta zerinde altm kaltm konusuna katt bir zellik vard. Eer kaynaklarmda bu kavrama rastlamam olsaydm, bu kabiliyeti bilemiyecek ve karlatmda bu nedir diyerek saa sola bakacaktm. O nedenle bu hafta boyunca, final anahtar szcnn Java diline saladklarn incelemeye altm. Hereyden nce ie, kaltm ile balamam gerektiini dnyordum. final anahtar
125

kelimesinin kullanlabildii alanlardan bir tanesi metodlard. Ancak sadece metodlara deil, deikenlere, snf rneklerine ve snflarada uygulanabiliyordu. Bunlarla birlikte kaltm sz konusu olduunda final metodlardan bahsetmeden geilemiyeceini bu haftaki almalarmdan anlamtm. e ncelike final kelimesinin, metodlara katt anlam tanmlamakla balamak gerekir diye dnyorum. Bir final metod, Temel snfta uygulandnda, tretilen snflarda iptal edilemeyen metodlar belirtir. Yani override ileminden bahsetmek mmkn deildir. Bu etkiyi ispat etmek iin her zaman olduu gibi kahvemden bir yudum aldm ve bir rpda aadaki kodlar yazverdim. Tek amacm, final metodlarn treyen snflarda yeniden yazlp geersiz klnp klnamyacayd. class Temel { final void Yaz() { System.out.println("Temel snf Yaz Metodu"); } } class Tureyen extends Temel { public void Yaz() { System.out.println("Tureyen snf Yaz Metodu"); } } public class FinalDeneme { public static void main() { Tureyen t=new Tureyen(); t.Yaz(); } }

126

Uygulamay derlediimde, mesaj ile karlatm.

aadaki

derleme zaman

hata

Her ey sonderece akt. Gerektende temel snflarda final olarak tanmlanan metodlar, treyen snflarda override edilemiyorlard. Final anahtar kelimesinin kabiliyetleri sadece metodlara yaptrdklar ile snrl deildi. rnein final alanlar vard. Deikenleri final olarak bildirdiimizde, onlara ilk deerlerin atanmasndan sonra, deerlerini deitiremiyorduk. Bu aslnda C# dilinde constant deikenlerden farkl deildi. Yani uygulamada deeri bir kere atandktan sonra deimesini istemediimiz deikenler iin kullanyorduk. Final olarak belirlenen deikenler ile ilgili ilgin olan nokta, deer atamalarnn alma zamannda (runtime) veya derleme zamannda (debug time) yaplabilmesiydi. Yani istersem, final bir deikene ilk deer atamasn alma zamannda gerekletirebilirdim. Ancak alma zamanna kadar deeri belli olmayan bir deiken nasl olabilirdi diyede dnmeye balamtm. Tam o srada imdadma Math snfnn rastgele saylar retmekte kullanlan, random metodu yetiti. Bu metod alma zamannda, rastgele saylar retebilirdi. Dolaysyla rastgele retilen bir deeri, programn almas boyunca sabit bir deer olarak saklamak iin final anahtar kelimesi kullanlabilirdim. Bu bilgiler nda, konuyu daha iyi kavrayabilmek iin, hemen basit bir rnek gelitirmeye karar verdim. public class FinalAlanlar { final static double deger2;

127

public static void main(String[] args) { final int deger1=7; deger2=0.125; final int deger3=(int)(Math.random()*10); Yaz(deger1,deger2,deger3); deger2=100; deger1=8; deger3=(int)(Math.random()*5); Yaz(deger1,deger2,deger3); } static void Yaz(int a,double b,int c) { System.out.println("Deger1="+a); System.out.println("Deger2="+b); System.out.println("Deger3="+c); } } Uygulamada yapmak istediim, final olarak belirlenmi alanlarn deerlerini deitirip deitiremiyeceimdi. Bu haliyle alan uygulama bana 4 adet derleme zaman hatas verdi.

128

lk gze arpan, deger2, deger1 ve deger3 deikenlerine yeni deerlerin final deikenler olduklar iin atanamyacayd. Dier taraftan dikkatimi eken bir baka nokta, ilk deer atamas yapmadm deger2 deikeni iinde, sonradan yaptm ilk deer atamasnda hata almamd. Buradan, final olarak tanmlanan deikenlere tanmlandklar anda deer atanmas gerektii sonucuna varyordum. Ama gerekten durum bylemiydi? ncelikle koddaki hatalarn saysn indirgemem gerektiini dnerek harekete getim. Bir yudum scak kahve ve ardndan aadaki kodlar uygulamadan kardm. deger2=100; deger1=8; deger3=(int)(Math.random()*5); Yaz(deger1,deger2,deger3); imdi uygulamay yeniden derlediimde, hata saysnn bire dtn ama deger2 iin yaplan atamada halen hata aldm grdm.

O halde yaplacak tek bir ey vard, deger2 nin deerini tanmland satrda belirlemek. Kodlar son olarak aadaki hale getirdiimde herhangibir hata mesaj almadan altn grdm. Gerektende final olarak belirlenmi alanlar programn almas esnasnda deitirilemiyorlard. public class FinalAlanlar { final static double deger2=0.125;

129

public static void Main(String[] args) { final int deger1=7; // deger2=0.125; final int deger3=(int)(Math.random()*10); Yaz(deger1,deger2,deger3); } static void Yaz(int a,int b,int c) { System.out.println("Deger1="+a); System.out.println("Deger2="+b); System.out.println("Deger3="+c); }

Dier taraftan aklma taklan bir nokta vard. Final olarak belirtilmemi bir alana ilk deer atamadmzda java derleyicisi bu deikenin trne gre bir ilk deer atamas yapyordu. rnein uygulamada double tipinden bir deiken tanmlayp buna ilk deer atamas yapmassak derleyici bizim iin bu deikene balang deeri olarak 0.0 deerini atyordu. Oysa deikeni final olarak belirttiimizde, derleyici bizim iin varsaylan bir deer atams yapmamakta, stne stelik birde hata mesaj vermekteydi. Bunu grmek iin uygulamaya deger4 isminde double veri trnde bir deiken ekledim. Ancak herhanbiri deer atamadm. static double deger4;

130

Daha sonra, bu degeri ekrana yazdrdmda derleyicinin 0.0 deerini atadn grdm. Ancak, bu deikeni final olarak belirttiimde, final static double deger4; ve program derlediimde aadaki hata mesajn aldm.

Elde edilen bu hata mesaj bana, final olarak tanmladm deikenlere mutlaka ilk deer atamas yapmam gerektiini ve hatta bu atamay deikenleri tanmladm yerde yapmam gerektiini gsterdi. Final anahtar kelimesinin deikenlerce kullanlmas bu ekildeyken, pandorann kutusu almaya devam ediyor ve iinden snf nesne rnekleri kyordu. Final anahtar kelimesini , nesne rneklerinede uygulayabilir ve bylece bu nesnelerin programn almas boyunca sadece bir kez yaratlmasn salayabilirdik. Bu durumu aratrmak amacyla aadaki kodlar yazdm. Burada tanmladm bir snfa ait nesneyi final anahtar kelimesi kullanarak oluturdum ve daha sonra ayn nesneyi tekrardan oluturmaya altm. class Kimlik { String ad="Burak"; String soyad="SENYURT"; int id=1000; public void Yaz() { System.out.println(ad+" "+soyad);

131

} public class FinalAlanlar { public static void main(String[] args) { final Kimlik personel1=new Kimlik(); personel1.Yaz(); personel1=new Kimlik(); } } Uygulamay derlediimde aadaki hata mesajn aldm.

Sonu olarak, final olarak oluturulan bir snf rnei bir kere oluturulabiliyordu. Dier yandan final olarak tanmlanan bu snfn yelerine normal olarak eriilebiliyordu. Final anahtar kelimesinin, bir snf rneinin sadece bir kere retilmesini salamas benim aklma baka bir ey getirmiti. Acaba bir snfn yapc metodlarna final anahtarn ekleyebilirmiydim? Nede olsa final anatar kelimesini snf metodlar ile birlikte kullanabiliyorduk. Bunun anlamann yolu denemekten geiyordu. nce aadaki varsaylan yapcy ekleyerek ie baladm. final public Kimlik() { } Program derlediimde aadaki hata mesajn aldm.

132

Belkide, final anahtar szcnn yerinden kaynaklanyordur diye dndm. Bu sefer final anahtar kelimesini public tanmndan sonraya aldm. Ancak yine ayn hata mesajn elde ettim. Aklma bu kez parametre alan bir yapcda final anahtarn kullanmak geldi. Nitekim yukardaki durum belkide varsaylan yapclara hast. final public Kimlik(int YeniID) { id=YeniID; } Ancak sonu yine deimedi. Demekki final metodlar tanmlayabiliyor ancak final yapclar oluturamyordum. Tabi kendi kendime neden final yapclar oluturmaya alaym ki dedim. Biraz anlamsz geldi ama neleri yapamyacam grmem asndanda bir yerde iyi oldu. Final anahtar szcn metodlara uygulayarak kaltmda overridelar engellemeyi, deikenlere uygulayarak program boyunca deitirilemeyen deikenler elde etmeyi, snf nesne rneklerine uygulayarak ayn nesnenin tekrar tretilememisini salamay, rendikten sonra dahada fazlasnn olabileceini hi dnmemitim. Meerse srada parametreler varm. Bir metodun parametrelerini final olarak tanmlayabilir ve bu sayede metodlara gelen parametre deerlerinin deitirilmesini engelliyebilirdim. Nasl m? class Hesaplar { double UsAl(final double sayi,final double us) { return Math.pow(sayi,us);
133

} public class FinalAlanlar { public static void main(String[] args) { Hesaplar islem1=new Hesaplar(); System.out.println(islem1.UsAl(2.4,1.25)); } } Bu uygulamada, Math snfnn pow metodunu kullanarak, double tipinden bir saynn double deerden ssn aldm. nemli olan ksm UsAl metodunda, parametre deerlerinin final olarak belirlenmesiydi. imdi bu metod ierisinde, gelen parametre deerlerini deitirmeye almalydm. double UsAl(final double sayi,final double us) { sayi=1.1; us=3.1; return Math.pow(sayi,us); } Uygulamay bu hali ile derleyip altrdmda,

grlen hata mesajn elde ettim. Demekki, metod parametreleri, final olarak bildirilirse, metod iinde deerleri deitirilemiyordu. Ancak parametreye gnderilen deerlerin verildii yerlerde bu durum sz konusu deildi. Bu tip parametreye sahip metodlar, deerlerin kesinlikle ieride deitirilmemesini istediimiz durumlarda kullanabilirdim.

134

Herhalde final ile ilgili pek ok ey hallolmutu demelimiydim acaba diye dnrken, kitaplarmn birisinde final snflar isimli bir balk grverdim. Evet sanrm daha herey bitmemiti. Kahvem bitmiti ancak final anahtar kelimesinin ilevsellikleri halen daha bitmemiti. Yinede final snf kavram faydal ve incelenmeye deer bir kavramd. Final olarak belirtilen snflarn en nemli zellii, C# dilindeki sealed anahtar szcnn ilevselliine sahip olmalardr. Yani final olarak tanmlanm bir snftan baka bir snf kaltmsal olarak tretemeyiz. final class Hesaplar { double UsAl(final double sayi,final double us) { sayi=1.1; us=3.1; return Math.pow(sayi,us); } } class AltSeviye extends Hesaplar { } Buradaki basit kodlarda, Hesaplar isimli snf final olarak tanmladm. Sonrada, bu snftan kaltm yolu ile baka bir snf tretmeye altm. Elbette sonu olarak java derleyicisi beni uyard ve final olarak tanmlanm bir snftan baka bir snf tretemiyeceimi syledi.

Snflarn final olarak tanmlanmas, ierdii metodlarn veya deikenlerin final olarak alglanmas anlamna gelmiyordu tabiki. Sadece ve sadece snfn tretme amac ile
135

kullanlamyacan belirtiyordu. Final anahtar kelimesi ile ilgili elde ettiim bilgiler u an iin bunlarla snrlyd. lerleyen zamanlarda farkl ekillerde kullanmn grebilirmiyim bilemiyorum. Nitekim bende final olmu durumdaym. Hem kahvem bitti hemde pilim. Sanyorumki bir ara vermenin zaman geldi. Artk nmzdeki hafta boyunca, polimorfizm konusunu incelemek iin bana gerekli olan enerjiyi depolamam gerekiyor.

Blm 9: Bukalemun Bu hafta boyunca, yaknlardaki ev hayvanlar dkkannda bulunan bir bukalemunu inceledim durdum dersem, herhalde bu adam sonunda ldrd diyeceksiniz. Yok henz ldrmadm. Aslnda bu hafta boyunca nesne ynelimli programlama dillerinin temel kavramlarndan birisi olan, ok biimlilii inceledim. Ben ok biimlilii bukalmenunlara benzettiim iinde, sanrm bu dkkanda bir sre oyalandm. Belkide bukalemundan bana ok biimliliin ne olduunu sylemesini bekliyordum dersem herhalde gerekten ldrd bu adam diyeceksiniz. Yok henz ldrmadm :) Nasl ki bukalemunlar, bulunduklar ortamn artlarna uyuyor ve ok deiik klklara yada biimlere brnebiliyorlarsa, nesne ynelimli bir programlama dilindede bir nesne, bukalemunla ayn tarz davranlar gsterebilmelidir. Bu nesne ynelimli programlama dillerinin doasnda olan nemli bir zelliktir. Ancak, ok biimlilik, kavram olarak tek bana var olmasna ramen, nesne ynelimli programlama dili tekniinde, kaltmn bir sonucu ve bir paras olarak karmza kmaktadr. Gerektende, ok biimlilik ve kaltm ii ie gemi iki nemli, nesne ynelimli programlama kavramdr. Normalde snf kavram, arkasndan gelen kaltm ve bunlara bal olarak ortaya kan ok biimlilik ile, kahveleri itike java dilinin nesne ynelimli temellerinide iyice anlamaya balam olduumu dnyorum. Ancak bu kavramlar genelde soyut nitelikler olduundan tanmlar ile anlalmalar gerekten zor oluyor. te ben bu gibi durumlarda, her zaman basit ve aptalca dnmeye alarak, olay en basit hali ile ele alabileceim
136

rnekler gelitirmeye alrm. Aynen bu kahve molas iin, incelemeyi dndm ok biimlilik kavramnda olduu gibi. Ancak yinede ilk rneime balamadan nce, kafamda basit ama etkili bir ok biimlilik tanm oluturmam gerektii dncesindeyim. Bu amala u tanmn ok biimlilie uygun olduu kansndaym. "ok biimlilik bir nesnenin davran ekillerinin duruma gre deitirilebilmesidir." Aynen, bulunduu ortamn artlarna gre renklerini mkemmel bir biimde ayarlayan sevimli bukalemun bugi gibi. Bugi bu ii gerekten ok iyi baaryor. Ancak benim benzer ilevsellii bir snf nesne rneine ykleyebilmem iin bilmem gereken yada sahip olmam gereken baz temel elementler var. Kaltm, override ve late binding.Kaltm nceki kafein molalarnda rendiime gre ve override etmeyi bildiime gre dorudan ok biimlilie geebilirim sanyorumki. Artk kollar svayp bu kavrama giriimi salayacak ilk rneimi gelitirmemin zaman geldi. Bir yudum kahvenin ardndan, aadaki kodlar oluturdum. Burada kaltm ilikisi olan snf tanmlamalar ve temel snfta tanmlanp treyen snflarda override edilen basit metodlar mevcut. Amacm ok biimlilii temel snf trnden bir nesneye uygulamak. Uygulamak ama bu nasl olucak ve ne ie yaryacak? Asl cevaplanmas gereken sorular ite bunlar. ncelikle tabiki rnei yazp baarl bir ekilde derlemem gerekiyor. class TemelSinif { public void Yaz() { System.out.println("Ben TEMEL sinifim"); } } class Tureyen_1 extends TemelSinif { public void Yaz() { System.out.println("Ben Tureyen_1 sinifiyim"); }
137

} class Tureyen_2 extends TemelSinif { public void Yaz() { System.out.println("Ben Tureyen_2 sinifiyim"); } } class Tureyen_3 extends TemelSinif { public void Yaz() { System.out.println("Ben Tureyen_3 sinifiyim"); } } public class Program { public static void Yaz(TemelSinif t) { t.Yaz(); } public static void main(String[] args) { Tureyen_1 t1=new Tureyen_1(); Tureyen_2 t2=new Tureyen_2(); Tureyen_3 t3=new Tureyen_3(); Yaz(t1); Yaz(t2); Yaz(t3); } } Kodu Program.java ismli ile kaydedip altrdmda aadaki sonucu elde ettim. derlediim ve

138

alma eklini grnce "Oha Falan Oldum Yani" dedim kendimce. Evet bir kod yazmtm ancak ok biimlilik bu kodun neresindeydi. Dahas sevimli bukalemun bugi nerelerdeydi; O kadar iyi kamufle olmutuki koda ilk baktmda onu grememitim. ncelikle kodun ierisinde yer alan snflarn hiyerarisine yakndan bakmak gerekiyordu. Bu amala u mehur uml diagramlar tekniini kullanmaya altm ve snflar aras ilikiyi aadaki ekilde olduu gibi kada dktm.

TemelSinif isimli base classtan treyen adet derived classm vard elimde. Ayrca Temel snfta tanmlanan Yaz isimli metod treyen snflar ierisinde iptal edilerek yeniden yazlyordu (override). Buraya kadar her ey gayet akt. Bu noktada benim iin nemli olan kilit nokta Program snf ierisindeki Yaz metoduydu. public static void Yaz(TemelSinif t) { t.Yaz(); } Bu metodun ilgin olan yan, TemelSinif trnden bir nesne rneini parametre olarak almas ve ald nesneye ait Yaz metodunu armasyd. te u kafalar kartran ok biimlilik buydu ve bizim bugide ok gzel ekil deitirerek t nesnesi

139

oluvermiti. Program snfnn main metodundaki kod satrlar ok biimliliin kullanlmasnn bir yolunu gstermekteydi. public static void main(String[] args) { Tureyen_1 t1=new Tureyen_1(); Tureyen_2 t2=new Tureyen_2(); Tureyen_3 t3=new Tureyen_3(); Yaz(t1); Yaz(t2); Yaz(t3); } Main metodunda treyen snflardan 3 farkl nesne tanmlanmt. Her bir nesnenin Yaz metodunu ayr ayr arabilirdim. Ancak bunun yerine, tm bu snflarn tredii, temel snf trnden bir nesne rneini parametre alan bir metodu armay ve buradaki treyen snf nesnelerini bu metoda gndermeyi tercih etmitim. Peki olan olay tam olarak neydi? rnein Yaz(t1) ile ne gibi ilemler gerekletiriliyordu? Yaz(t1), Program snfm ierisindeki static Yaz metodunu aryor ve buna t1 nesnesini parametre olarak gnderiyordu. Yaz metodunun parametresi ise t1 nesnesinin tretildii TemelSinif trndendi. Bingo. te ok biimliliin en temel noktasn yakalamtm. Treyen nesne ne olursa olsun, Yaz metodu sadece tek bir nesne kullanyor ve bu tek nesne zerinden, kendisine atanan treyen snfa ait yeleri altryordu. Dolaysyla t1 nesnesi Yaz metoduna aktarldnda, TemelSinif trnden t nesnesine atanm ve doal olarak t.Yaz() kod satr ile t1in Yaz metodu arlmt. Bunu salayan elbetteki TemelSinifin treyen snf yelerine eriebiliyor olmasyd. ok biimlilik burada Program snfnn static Yaz metodunun gerekletirdii ilevsellikti. Hangi snfn Yaz metodunun altrlaca burada belli oluyor dolaysyla minik bugi t nesne rnei, artlara uygun hareket ediyordu. in suyunu kartp programn alma biimini grafie dkmeye karar verdim. Sonu olarak ikinci bir kahve fincan doldurmam gerekmiti ama

140

kafamdaki balamt.

ekillerde

ok

biimsel

anlamlar

kazanmaya

ekilde grld gibi Program snfndaki static Yaz metodu, alma zamannda arldnda, TemelSinif trnden bir t nesnesi tanmlanyor ve bu t nesnesine, Yaz metodunun arlmasnda gnderilen treyen snf nesnesi atanyor. Bunun sonucu olarak bu t nesnesi, gelen snfn heap blgesindeki adresini referans etmeye balyor. Doal olarak, t.Yaz metodu ilede,parametre olarak gelen treyen snf nesnesinin Yaz metodu arlm oluyor. Burada aslnda nemli bir nesne ynelimli programlama teknii kavramda mevcut. Late Binding(Ge Balama). Yukardaki eklin bana syledii en nemli ey olaylarn alma zamannda gerekleiyor olmas. Bunun ifade ettii ey ise olduka nemli. Nitekim, program almaya baladktan sonra, biz static Yaz metodunu ardmzda, bu metod iinden hangi treyen snfn Yaz metodunun arlaca henz bilinmemektedir. Bu ancak, treyen snf nesnesi metoda parametre olarak atanp, TemelSinif trnden t nesnesine atandnda belli olucaktr. Yani hangi Yaz metodunun arlacana alma zamannda karar verilmektedir. te bu olay, ge balama (late binding) olarak adlandrlmakta olup, ok biimliliin bir paras olarak, nesne ynelimli programlama dilinin temel yap talarndan birisi olarak karmza kmaktadr.
141

ok biimlilii bylece tanmaya balam oldum. Peki bu kavram benim nerede iime yarayabilirdi. Bu cevaplanmas gerekten ok zor bir soru. Bence esas olan ok biimliliin bize salam olduu fayday anlamaya almak. Ancak yukardaki rnei normal programlama teknikleri ile yapmaya alsaydk acaba nasl bir kod yazm olurdu. Yani ok biimlilik uygulamadan. Bu noktada uzun zamandr nesne ynelimli diller ile uraan birisi olarak bu eit bir kodu yazmak benim iin olduka zor oldu. Sonunda aadaki gibi bir sonu ortaya kt. ekilse adan en nemlisi alma ekli asndan olduka kt bir rnek. class TemelSinif { public void Yaz() { System.out.println("Ben TEMEL sinifim"); } } class Tureyen_1 extends TemelSinif { public void Yaz() { System.out.println("Ben Tureyen_1 sinifiyim"); } } class Tureyen_2 extends TemelSinif { public void Yaz() { System.out.println("Ben Tureyen_2 sinifiyim"); } } class Tureyen_3 extends TemelSinif { public void Yaz() {

142

} }

System.out.println("Ben Tureyen_3 sinifiyim");

public class Program4 { public static void Yaz(Object obj) { if(obj instanceof Tureyen_1) { Tureyen_1 t1=(Tureyen_1)obj; t1.Yaz(); } else if(obj instanceof Tureyen_2) { Tureyen_2 t2=(Tureyen_2)obj; t2.Yaz(); } else if(obj instanceof Tureyen_3) { Tureyen_3 t3=(Tureyen_3)obj; t3.Yaz(); } else if(obj instanceof TemelSinif) { TemelSinif t=(TemelSinif)obj; t.Yaz(); } } public static void main(String[] args) { Tureyen_1 t1=new Tureyen_1(); Tureyen_2 t2=new Tureyen_2(); Tureyen_3 t3=new Tureyen_3(); Yaz(t1); Yaz(t2); Yaz(t3); }

143

rnekte ok biimliliin olmadn varsayarak hareket ettim. Bu durumda, ortak static Yaz metoduna gnderdiim nesnelerin tipleri belli olmad iin, Object snfndan bir nesne rneini parametre olarak belirtmem gerekti. Daha sonra bu metoda gnderilen nesnelerin hangi snf tipinden olduklarn renmek amacyla instanceof anahtar kelimesinin kullanld if bloklarn iin iine kattm. Bu if bloklarnda nesnenin hangi tipten olduuna baklyor ve daha sonra bu nesne iin yeni bir rnek new operatr ile oluturuluyor ve daha sonra bu yeni nesne rnei zerinden gerekli Yaz metodu altrlyordu. Oysaki ayn rnei ok biimlilik yolu ile ne kadar basit ve anlaml yapmtk. Zaten kim sylemi ise doru sylemi. "Basit ama aptalca dnmeye devam et." Dolaysyla sonu olarak ok biimliliin faydas hakknda unu syleyebilirim artk; "ok biimlilik sayesinde, alma zamannda nesne davranlarna eitlilik katabilmekteyiz." ok biimlilii baka nasl kullanabiliriz diye dnmeye baladm srada aklma fabrika alanlar geliverdi. Bir fabrikann alanlarna ilikin bilgileri tutan temel bir snf olduunu dndm. Bu sfntan treyen ve iiler arasndaki kategorileri birer snf olarak temsil eden tremi snflar olucakt. Temel snfta tanmlanm, saat creti zerinden maa hesab yapan bir metodu, treyen snflarda yeniden yazdm yani override ettim. Her treyen snfn kendisine gre bir saat creti olacandan, maa hesaplamalarda farkl olucakt. Programn ierisinde, tm fabrika iilerinin, temel snftan bir dizi ierisinde tutulduunu dndm, bu diziye ok biimlilii uygulayarak, tek bir nesne zerinden, hangi treyen snfa ait metodun altrlacannn alma zamannda karara balanmasn salamaya altm. O halde ne duruyorum. Bu rnei gelitirip ok biimlilikle iligli bilgileri pekitirmeye karar verdim ve kahvemden bir frt ekip uygulamay yazmaya baladm. class Isciler { public int hesapla() { return -1;
144

class Kidemli_Isciler extends Isciler { int saatUcreti=100; int saat; public Kidemli_Isciler(int s) { saat=s; } public int hesapla() { return saatUcreti*saat; } } class Vasifli_Isciler extends Isciler { int saatUcreti=80; int saat; public Vasifli_Isciler(int s) { saat=s; } public int hesapla() { return saatUcreti*saat; } } public class Program2 { public static void main(String[] args) { Isciler[] isciler=new Isciler[3];

145

isciler[0]=new Kidemli_Isciler(10); isciler[1]=new Vasifli_Isciler(5); isciler[2]=new Kidemli_Isciler(20); for(int i=0;i<isciler.length;i++) { int ucret=isciler[i].hesapla(); System.out.println(ucret); } } }

ok biimlilik ile ilgili gzden kaan bir ayrntyda almalarm yaparken farkettim. ok biimliliin uygulanmas aslnda programlarn alma performans zerinde azaltc bir etki yaratmaktayd. Dolaysyla ge balama sz konusu olduunda uygulamann verimi dyordu. Bu amala ilk yazdm ie yaramayan ancak ok biimliliin ne olduunu gsteren minik program parasnn dahada aptallatrlm srmn gz nne aldm. class TemelSinif { public void Yaz() { System.out.println("Ben TEMEL sinifim"); } } class Tureyen_1 extends TemelSinif {

146

public void Yaz() { System.out.println("Ben Tureyen_1 sinifiyim"); } } public class Program3 { public static void Yaz(TemelSinif t) { t.Yaz(); } public static void main(String[] args) { Tureyen_1 t1=new Tureyen_1(); TemelSinif t=new TemelSinif(); Yaz(t1); Yaz(t); }

Burada verimi deren neydi acaba? Biraz dnnce aslnda bunun sebebi anlalabiliyordu. Olay Yaz(t1) armnda kendisini gsteriyordu. Yaz(t1) ile, static Yaz metodu arlyor TemelSinif nesnesi trnden t snfna ait Yaz metodu altrlyordu. te alma zamannda java sanal makinesi, bu noktada ge balama olup olmadn kontrol etmekteydi. Burada TemelSinif t nesne rneine Treyen_1 snfndan bir nesne atanmt. Dolaysyla burada ge balamadan sz edebilirdik. Bunu gren JVM bu ilemin ardndan treyen snfn Yaz metodunun override edilip edilmediine bakcak ve ondan sonra bu metodu arcakt. te bu zincir alma verimini dren bir etken olarakta karmza kyordu. ok biimlilik (Polimorphism) kavram nesne ynelimli programlama kavramlarnn nemli bir eleman olarak artk kafamda iyice ekillenmiti. Artk Javada ilerlemeye devam edebilirdim. Ama nce alverie kp kahve ve st tozu stoklarm yenilemem gerekiyor.

147

Blm 10: Soyutlama (Abstraction) Geen hafta boyunca soyutlama kavramn irdelemeye altm. Bunu yaparken pek zorlanmadm nk C# dilinden soyutlamann ne olduunu biliyordum. Ancak bu kavram zaman zaman kafa kartrc bir hal alabilmekteydi. En byk sknt soyutlamalarn tam olarak nasl ifade edildikleri ve kavramsal olarak neyi yada neleri belirtebilecekleriydi. C# dilinde soyutlamalar anlamaya altm ilk zamanlarda, ayn satrlar 4 hatta 5 kez okuduumu ve uzun sreler ne olup bittiini anlamak iin abaladm hatrlyorum. Bu sknty daha nce yaadmdan, imdi java dilinide soyutlamalar incelerken de benzer durumlar ile karlaabileceim korkusu ile bu haftaki soyutlama almalarm daha bir titiz yapma zorunluluunu hissettim. Neyseki C# dilinden pek bir fark yokmu. En nemli konu, soyutlamann tam olarak snflara ve ierisinde yer alan metodlara uygulandn bilmek. Peki o halde soyut snf nedemek? Soyut snflar, somut olmayan snflar olarak tanmlyarak bu kavram aklamaktan kurtulabilirim. Keza, somut olmayan snflarda soyutturlar. Bu aslnda, Japonlarn yada inlilerin (hangi tarafn bu fikrin orjinaline sahip olduunu bilmiyorum), Ying Yang felsefesinin bir sonucudur. Ancak bu tanmlama her nekadar geerli bir tanmsada, fazla bir ey ifade etmemektedir. Asl olan, soyut snflarn, kaltmn bir paras olarak normal bir snfn sahip olabilecei yeler dnda, soyut metodlara sahip oluu ve bu soyutlamadan treyen snflardada, soyutlanm metod bildirimlerini mutlaka ve mutlaka uygulamak zorunda brakt yaplardr. Bu adan bakldnda, soyut snflarn, kaltmda birletirici bir rol stlenmenin yan sra, treyen snflarn zorunlu olarak izlemeleri gereken bir rehber oluturduunuda syleyebiliriz. Soyutlamann bu uzun ama ok ey ifade eden tanm yinede bu konuyu anlamak iin yeterli deildir. Nitekim, soyutlamda
148

dikkat edilmesi gereken ve gze arpan pek ok nokta vardr. Ama yinede, u an iin, soyutlamay gsteren basit bir rnek ile ie girimenin daha faydal olaca kansndaym. Her eyden nce, soyut snflarn ve metodlarn nasl tanmlandn bilmemiz gerekiyor. Kaldki soyutlamann nemli yaptalarn oluturan kurallar bu temeller zerine kurulu olucaktr. Bu amala, aadaki gibi basit bir rnek gelitirdim. abstract class SoyutTemel { public static void Yaz() { System.out.println("Ben soyut temel sinifim"); } abstract public void Kimlik(); SoyutTemel() { } int deger=40; } class Tureyen1 extends SoyutTemel { public void Kimlik() { System.out.println("Ben SoyutTemel siniftan tureyen Tureyen1"); } } class Tureyen2 extends SoyutTemel { public void Kimlik() { System.out.println("Ben SoyutTemel siniftan tureyen Tureyen2");

149

public class Soyutlama { public static void main(String[] args) { Tureyen1 t1=new Tureyen1(); Tureyen2 t2=new Tureyen2(); t1.Kimlik(); t2.Kimlik(); } } rnei derleyip altrdmda aadaki ekran grntsn elde ettim.

Bu uygulamada ilk dikkati eken nokta soyutlamann uyguland snflarn tanmlanma eklidir. Bir snf soyut olucaksa, abstract anahtar sz ile tanmlanr. abstract class SoyutTemel Bu anahtar szck ile SoyutTemel snfnn soyutlamay uygulayacan belirtmi oluruz. Peki bu uygulamann getirdii etkiler nelerdir? lk olarak unu syleyebilirim. Soyut bir snftan herhangibir nesne rnei tretilemez. Bunun sebebi, soyut snflarn birletirici zelliklerinin yansra, abstract metod tanmlamarn iermesidir. abstract public void Kimlik();

150

Burada grld gibi abstract metodlar, sadece bir metod bildiriminden ibarettir. yleki bu metod bildirimi, bu soyut snftan treyen snflarda mutlaka ama mutlaka override edilmelidir. Dolaysyla, eer bir soyut snf nesne rnei oluturulabilseydi, bu metod bildirimlerine eriilmesi son derece anlmasz olurdu. te bu nedenle, soyut snflarn rneklendirilmesi yasaklanmtr. Bununla birlikte bu yasaklama, sanld gibi, soyut snflarn herhangibir yaplandrc ieremeyeceini gstermez. Nitekim yukardaki rneimizde, abstract snfmz iin bir adet varsaylan yapc metod yazlmtr. O halde, java dili abstract bir snfn nesne rneini, new operatr kullanld yerde denetleyecektir. rnein, uygulamamzn Main metodu ierisinde SoyutTemel abstract snfndan bir nesne rnei yaratmaya alalm. Bu durumda java derleyicisi derleme zamannda bizi bir hata ile uyaracaktr. public static void main(String[] args) { Tureyen1 t1=new Tureyen1(); Tureyen2 t2=new Tureyen2(); t1.Kimlik(); t2.Kimlik(); SoyutTemel t=new SoyutTemel(); }

Dier yandan, soyut snflara ait nesne rnekleri tanmlayamasakta, soyut snflara ait nesneler tanmlayarak (yani sadece nesne tanmlama, oluturmak deil) bu nesnelere, tremi snf nesnelerinin referanslarn aktarabiliriz. Bu bize,

151

kaltmn en nemli talarndan olan ok biimlilii uygulama frsatn verir ve dostumuz bugiyi hatrlamamz salar. Nitekim, soyut snflar, kaltmn bir paras olarak, ok biimliliide bir ekilde desteklemelidirler. Bu kaltmn doas gerei ortaya kan bir sonutur. Bu anlamda yukardaki rnee ok biimlilii aadaki gibi uyguladm. public class Soyutlama { public static void Yazalim(SoyutTemel[] t) { for (int i=0;i<t.length;i++) { t[i].Kimlik(); } } public static void main(String[] args) { Tureyen1 t1=new Tureyen1(); Tureyen2 t2=new Tureyen2(); SoyutTemel[] dizi=new SoyutTemel[2]; dizi[0]=t1; dizi[1]=t2; Yazalim(dizi); } } Uygulamay bu haliyle derleyip altrdmda aadaki ekran grntsn elde ettim.

152

Burada ok biimlilii uygularken, SoyutTemel snfndan bir nesne dizisi kullandm. Ancak buradaki new operatr, bir nesneye ait yaplandrclar aran new operatr ile ayn deildir. Tek yaptmz, SoyutTemel snfndan nesneler tayacak iki elemanl bir dizi tanmlamaktr. Keza, bu dizinin elemanlar, abstract snfmzdan treyen snf nesne rnekleridir. ok biimlilii, Yazalim metodunda uyguluyoruz. Burada SoyutTemel abstract snfndan nesneler, kendisine atanan treyen snflara ait Kimlik metodlarn aryor. te bylece abstract snflarada ok biimlilii uygulatabildiimizi grm oluyoruz. Abstract snf tanmlamalarnda dikkat eken bir dier unsurda, bu snfn abstract metodlar dndada normal snflarn sahip olduu yelere sahip olabilmesidir. Normal metodlar veya alanlar. Normal bir metodu treyen snflara ait nesneler zerinden kaltmn bir gerei olarak arabiliriz. Ancak bu metodlar, abstract snfndan bir nesne rnei zerinden aramyacamzda kesindir. nk, abstract snflardan bir nesne rnei oluturamayz. Byle bir durumda tanmland snfn nesne rneine ihtiya duymayan static metodlar kullanabiliriz. Bu aslnda, herhangibir rneinin kesinlilikle tretilmesini istemediimiz nesnelere ait bir takm metodlar uygulatmakta kullanlabileceimiz bir tekniktir. Gelelim abstract snflardaki yapc metodlarn ileyiine. Bir abstract snfa ait nesne rneinin kesinlikle oluturulamyacan biliyoruz. Ancak bir abstract snfn yapclar ierebildiinide bilmekteyiz. Bununla birlike bitmek tkenmek bilmeyen bilgilerimiz yannda, abstract snftan treyen bir snfn nesne rneinin, kaltmn doas gerei ilk olarak abstract snf ierisindeki yapc metodu ileyeceinide biliyoruz. Buraya kadar aslnda benim iinde enterasan gelebilecek bir olgu yok. Ancak aadaki gibi bir kod ne gibi sonular dourabilir? SoyutTemel() { Kimlik(); }

153

Burada abstract snfn ierisinden, abstract olarak tanmlanm Kimlik metodu arlmtr. Bu metodun arlaca kesindir. nk, abstract snftan tretilen bir snfn nesne rnei oluturulurken nce, abstract snftaki yapc ve bu yapc iindende, treyen snftaki override edilmi abstract metod arlacaktr. Ancak iin iine, yapclar ierisinde ilk deer atamalar girdiinde durum biraz garipleir. Bunu aklayabilmem iin aadaki gibi bir rnek gelitirmem gerekti. abstract class SoyutTemel { public static void Yaz() { System.out.println("Ben soyut temel sinifim"); } abstract public void Kimlik(); SoyutTemel() { System.out.println("Soyut metoddan once"); Kimlik(); System.out.println("Soyut metoddan sonra"); } int deger=40; } class Tureyen1 extends SoyutTemel { int No; public void Kimlik() { System.out.println("Ben SoyutTemel siniftan tureyen Tureyen1 Kimlik No:"+No); } Tureyen1() { System.out.println("TUREYEN 1 YAPICISI"); No=154528;

154

class Tureyen2 extends SoyutTemel { int No; public void Kimlik() { System.out.println("Ben SoyutTemel siniftan tureyen Tureyen2 Kimlik No:"+No); } Tureyen2() { System.out.println("TUREYEN 2 YAPICISI"); No=458569; } } public class Soyutlama { public static void Yazalim(SoyutTemel[] t) { for (int i=0;i<t.length;i++) { t[i].Kimlik(); } } public static void main(String[] args) { Tureyen1 t1=new Tureyen1(); Tureyen2 t2=new Tureyen2(); SoyutTemel[] dizi=new SoyutTemel[2]; dizi[0]=t1; dizi[1]=t2; Yazalim(dizi); } }

155

ncelikle uygulamay inceleyelim. Tureyen snflardan bir nesne oluturulduunda, kaltmn bir gerei olarak, ilk nce SoyutTemel snfnn yapcs arlacaktr. Burada ise, treyen snflarda override edilen Kimlik metodu arlmtr. Kimlik metodu, override edildii snfn (Tureyen1,Tureyen2) yapcsndaki No deerini ekrana yazdrmaldr. Ancak durum byle olmaz. nk henz, SoyutTemel abstract snfnn yapcs sonlandrlmamtr. Bu nedenle, No alann deeri, java tarafndan integer deikenlerin alaca varsaylan deeridir, yani 0dr. Dolaysyla override edilen metod iinden, No alannn ilgili treyen snf yapcsnda belirlenen deeri elde edilememitir. Ancak abstract snfn yapcs ilevini bitirdikten sonra, treyen snftaki yapc arlacak ve No alannn deeri yapclarda belirlenen halini alcaktr. Bu nedenle uygulamann ekran kts aadaki biri olur.

Soyut snflarn, kaltmda, treyen snflar iin birletirici bir rol stlenerek, onlarn uygulamas gereken metodlar belirten bir rehber olduunu syleyebiliriz. Burada treyen snflara ynelik bir zorlamada sz konusudur. Nitekim, abstract snflarn tanmlanmas ile oluturulan abstract metodlar, mutlaka ve mutlaka treyen snflarda override edilmelidir. Sz gelimi yukardaki rneimizde, Tureyen1 snfnda Kimlik metodunu override etmediimizi dnelim. Bu durumda aadaki gibi bir derleme zaman hatas alrz.

156

Grld gibi derleyici, Kimlik metodunun abstract olmasna ramen, treyen snf ierisinde tanmlanmadn belirtiyor. Oysaki normal bir snfn kaltmda temel snf olarak rol oynamasnda, treyen snflarn, temel snftaki metodlar override etmek gibi bir zorunluluu yoktur. te buda abstract snflar normal snflardan ayran dier bir olgudur. Soyutlama ile ilgili temelleri atm dndm bir srada kafama olduka gzel sorular geldi. Nerde geldiini sormayn nitekim bunlar dnrken, Winston Churchill ile grmedeydim. Doruyu sylemek gerekirse bu adam her zaman dimam ayor. Acaba bir abstract snftan baka abstract snflar tretebilir miydim? Tretirsem, treyen abstract snflarda, abstract olmann bir gerei olarak, temel abstract snftaki abstract metodlar bildirmem gerekir miydi? Peki ya byle bir hiyeraride, en altta yer alan abstract snftan normal bir snf tretirsem, bu snf iinde, hiyerarideki abstract metodlarn akibeti ne olurdu? nce ie bir abstract snftan baka bir abstract snf oluturmakla baladm. abstract class TemelSoyut { abstract public void Metod1(); abstract public int Metod2(int a,int b); abstract public double Sec(); public static void Yaz() { System.out.println("BEN ABSTRACT TEMEL SINIFIM"); }

157

} abstract class TureyenSoyut1 extends TemelSoyut { } public class Soyutlama2 { public static void main(String[] args) { } } ncelikle programn baarl bir ekilde derlendiini syleyebilirim. lk aamada iki sorumun cevabn almtm. Soyut snflardan yeni soyut snflar tretilebiliyordu. Bununla birlikte, treyen soyut snf ierisinde, temel soyut snfta tanmlanm abstract metodlarn override edilme zorunluluu gibi bir durum sz konusu olmamt. Gelelim asl nemli noktaya. Yani treyen abstract snftan bir baka snf tretmeye. rnei biraz daha gelitirdim. Treyen abstract snf ierisinede baka abstract metod bildirimleri ekledim. abstract class TemelSoyut { abstract public void Metod1(); abstract public int Metod2(int a,int b); abstract public double Sec(); public static void Yaz() { System.out.println("BEN ABSTRACT TEMEL SINIFIM"); } } abstract class TureyenSoyut1 extends TemelSoyut { abstract public void YaziYaz(); }

158

class Deneme extends TureyenSoyut1 { } Bu haliyele uygulamay derledim ve aadaki gibi bir hata mesaj aldm.

Olduka artc bir durumla karlamtm. Derleyici u an iin sadece TureyenSoyut1 deki YaziYaz abstract metodunu override etmem gerektiini sylyordu. Oysaki, TureyenSoyut1 abstract snfda baka bir abstract snftan tremiti. Benim umduum, TemelSoyut snfnda yer alan ve override edilmeyen abstract metodlar iinde hatalar alabilmekti. Bana den ncelikle YaziYaz metodunu override etmekti. class Deneme extends TureyenSoyut1 { public void YaziYaz() { System.out.println("YAZI YAZIYORUM"); } } imdi uygulamay derlediimde, ilk defa grdm bir derleme hatas iin bu kadar ok sevinmitim. Bu kez derleyici, TureyenSoyut1 abstract snfnn tredii TemelSoyut snfndaki Sec metodunun override edilmediini belirtiyordu. Dnyalar benim oldu desem yeridir.

159

Bu hatalar sinsilesinin tek handikap byle tek tek ekrana gelmesiydi. Yani aslnda hata mesajndan, override edilmesi gereken tm metodlar iin bir uyar alamyordum. Yinede, tretilen abstract snflardan treyen snflarn abstract snf hiyerarisindeki tm metodlar override etmesi gerektii sonucuna varabilmitim. Soyut snflar ile ilgili olarak dikkat edilmesi gereken pek ok nokta var. Bu noktalar iyice kavrayncaya kadar, aadaki tabloda grld gibi not etmeyi uygun gryorum. Eitimde ezbercilie her zaman karymdr. niversite yllarndayken, kaln not defteleri ile birlikte rendiklerimi yanmda tardm. Taki rendiklerim zerinde yorumlar ve felsefik sylemlerde bulununcaya dek. O gnler geldiinde not defterlerini rafa kaldrrdm. imdi ise, yanmda not defteri yerine Laptop tayorum. Ama yinede ilk rendiim ve zerlerinde henz felsefik sylemler yapamadm kavramlar dosyalarda saklyor ve yeri geldike bakp hatrlyorum. te aadaki tabloyuda bu yaklam ile hazrladm. Soyutlamada Dikkate Deer Noktalar 1 2 3 4 5 Soyut snflardan nesne rnekleri oluturulamaz. Bir snfn soyut olabilmesi iin en azndan bir tane soyut metod bildirimine sahip olmas gerekir. Soyut snflardan tretilen snflar, soyut metod bildirimlerini mutlaka override etmelidirler. Soyut snflardan treyen nesne rneklerini, soyut snf nesnelerine referans olarak aktararak ok biimliliin uygulanmasn salayabiliriz. Soyut snflardan baka soyut snflarda tretilebilir.
160

6 7 8 9

Soyut metodlar private olarak tanmlayamayz. Soyut snflara ait yapclar tanmlayabiliriz. Ancak bu yapclar soyut tanmlayamayz. Static bir soyut metod bildirimi yapamayz. Soyut snflar ierisinde soyut metod bildirimleri dnda, normal metodlar ve alanlar tanmlayabiliriz.

Bu hafta boyunca soyutlama ile ilgili bu kavramlar inceledikten sonra, nesne ynelimli programlama dillerinde soyutlama ile ok sk kartrlan bir kavram incelemeye karar verdim. Sanrm bir sonraki kahve molamda, Interface (arayz) kavramn inceleyeceim.

Blm 11: Arayzler (Interfaces) Geen hafta boyunca, nesne ynelimli programlama dillerinde, aralarndaki farkllklar dnda kavramsal olarak birbirlerinden ayrlmakta zorlanan kavramlardan birisi olan soyutlamann Java dilindeki yerini aratrmtm. Soyutlama ile ilgili olarak incelemelerimi tamamladktan sonra, srada arayzlerin incelenmesine vard. C# programlama dilinden aina olduum arayzler, java dilindede yer almaktayd. Her zaman olduu gibi karmda bu iki kavram iin sorulan o mehur sorular topluluu bulunuyordu. Neden arayz, neden soyutlama, hangisini kullanmalym, kim daha avantajl vb...? Nesne ynelimli dilleri gelitirenlerin bile olduka karmak bir biimde cevaplayabilecekleri yada aklayabilecekleri bu ayrm anlamak iin ne kadar aba gstersemde, sonular hi bir zaman i ac olmamt. Ancak en azndan, arayzlerin kullanlmas ile soyutlama arasndaki temel farkllklar iyi bilmem gerektii kansndaydm. e ncelikle arayzlerin ne olduunu tanmlamakla balamakta fayda vard. Arayzlerin en belirgin zellii, soyut metod tanmlamalarnda olduu gibi metod bildirimleri iermesiydi. Dolaysyla arayzlerin, dier snflar iin yol gsterici olacak ekilde tanmalanan bir yap olduunu syleyebilirim. Bu tanm
161

itibariyle, soyut snflar ile arasnda ok byk bir benzerlik var. Her iki teknikte, kendilerini uygulayan snflara rehberlik etmek zere ortak bildirimlere izin veriyor. Soyutlamada bu, soyut snflar ierisindeki soyut metodlar ve kaltmn bir arada ele alnmas ile gerekletiriliyor. Arayzlerde ise durum daha farkl. Nitekim arayzler, soyut snflarda olduu gibi i yapan metodlar iermiyor. Onun yerine sadece metod bildirimlerini ve alan tanmlamalarn ieren ve kaltm yerine implementasyonun bir arada ele alnd bir teknik sz konusu. te bu noktada daha olayn banda, arayzler ile soyutlama arasndaki en temel fark grm oldum. Soyutlamada soyut metod bildirimleri haricinde i yapan metodlarn var olmas sz konusu iken, arayzlerde sadece metod bildirimleri yer almakta. u anda, bir arayzn nasl oluturulduunu ve bir snf tarafndan nasl kullanldn aka grme ihtiyac hissediyorum. te bu istein karlnda, her zaman olduu gibi anlamsz herhangibir i yapmayan ama kavram aklayan bir kod gelitirmem gerektii kansna varyorum. Olay sade ve basit olarak dnmek ve kavramlar zerinde younlamak u an ihtiyacm tek ey. interface IArayuz { void Yaz(); int Topla(int a,int b); } class Mat implements IArayuz { public void Yaz() { System.out.println("Arayuzden uygulanan Yaz metodu"); } public int Topla(int deger1,int deger2) { return deger1+deger2; } } public class Uygulama
162

public static void main(String[] args) { Mat m=new Mat(); m.Yaz(); int topla=m.Topla(10,20); System.out.println("10 + 20 ="+topla); }

} Uygulamay derleyip altrdmda aadaki sonucu elde ettim.

Sonutan daha ok benim iin nemli olan, arayz tanmlamasnn yapl ekli ve bu arayzn bir snfa uygulanyd. Bir arayz interface anahtar kelimesi ile tanmlanan ve sisteme bir class dosyas olarak kaydedilen bir yapdr. interface IArayuz Dier yandan bu arayz bir snfa uygulamak istediimde, implements anahtar szcn kullanmam gerekiyor. class Mat implements IArayuz Implements anahtar szc ile bu snfn belirtilen arayz uygulayacan ve bu nedenlede belirtilen arayz iindeki tm metodlar uygulamas gerektiini sylemi oluyoruz. C# dilinden kalma bir alkanlk olarak tanmladm arayzn bir Interface (arayz) olduunu daha kolay anlayabilmek amacyla, I harfini arayz adnn bana ekledim. Tanmladm Mat snf iinde arayzdeki tm metodlar override ettim. Bu bir zorunluluk.
163

Eer, arayz iinde tanml metodlardan override etmediim olursa, sz gelimi Yaz metodunu override etmessem aadaki gibi bir derleme zaman hatas alrm.

Arayzlerde tanmlanan metod bildirimleri ile, soyut snflarda tanmlanan soyut metodlar arasndada belirgin farkllklar mevcut. Hereyden nce arayzler iindeki metod bildirimlerinde abstract anahtar szcn kullanmyoruz. Bununla birlikte dikkatimi eken bir dier nemli noktada, arayz metod bildirimlerinin herhangibir eriim belirleyicisini kabul etmedii. Bu metodlar varsaylan olarak public kabul ediliyorlar ve public dndaki bir eriim belirleyicisi ile tanmlanamyorlar. Bu aslnda arayzlerin ierdii metod bildirimlerinin, dier snflara uygulandklarnda override edilebilmelerinin bir gereklilii olarak dnlebilir. Uygulamamda kullandm arayzdeki metodlarda baka trden eriim belirleyicileri kullanmaya altmda derleme zaman hatalar ile karlatm. interface IArayuz { private void Yaz(); protected int Topla(int a,int b); }

164

Grdm ki arayz iindeki metodlar public olmak zorundalar. Zaten bu sebepten dolayda varsaylan eriim belirleyicileri, arayzlerdeki metodlar iin public olarak belirlenmi. Arayzlerin kullanlmalarnn en nemli nedenlerinden biriside snflar zerinde oklu kaltma izin vermeleri. Normalde, C# dilinde snflar arasnda oklu kaltma izin verilmediini ve bu iin arayzler yardmyla gerekletirildiini biliyordum. Java dilinde de durumun byle oluu beni ok fazla artmad akas. Kahvemin bir sonraki yudumu oklu kaltm ile ilgili bir rnei gelitirmem gerektii konusunda beyin hcrelerimi uyaryordu. Ah keke birazda daha ie yarar rnekler oluturabilmeme yardmc olsa u kafein mereti. Neyse, nemli olan kavramlar iyi anlayabilmek ve nasl uygulandklarn teorik olarak en basit ekilde ifade edebilmek deilmi? O halde ne duruyorum. interface IArayuz { void Yaz(); int Topla(int a,int b); } interface IArayuz2 { int Karesi(int a); int Kup(int a); } class Mat implements IArayuz,IArayuz2 { public void Yaz() { System.out.println("Arayuzden uygulanan Yaz metodu"); } public int Topla(int deger1,int deger2) { return deger1+deger2; } public int Karesi(int deger) {
165

} public int Kup(int deger) { return deger*deger*deger; }

return deger*deger;

public class Uygulama { public static void main(String[] args) { Mat m=new Mat(); m.Yaz(); int topla=m.Topla(10,20); System.out.println("10 + 20 ="+topla); System.out.println("10 un karesi = "+m.Karesi(10)); System.out.println("10 un kubu= "+m.Kup(10)); } }

Burada yaptm, IArayuz1 ve IArayuz2 interfacelerini, Mat isimli snfa uygulamak. Bu ekilde, oklu kaltm salam oldum. Yani bir snf birden fazla arayz yesini override ederek bu hakk kazanm oldu. Yukardaki uygulamann alma eklini daha iyi anlamak amacyla da aadaki gibi bir ekil gelitirdim.

166

Arayzler ile ilgili bir dier nemli konu ise, farkl arayzlerin ayn isimli metodlar barndrmalar srasnda ortaya kabilecek sorunlar. Bunu daha iyi anlayabilmek iin, soruna neden olucak bir rnek gelitirmem gerekiyor. yleki, ayn isimli metod bildirimlerini ieren iki arayz bir snfa uygulamaya altmda, bir hata mesaj almalym. Gelmek istediim nokta aslnda overloading kavramnn temel niteliklerinden birisi. Ama nce rnei yazp zerinde dnmek gerektii kansndaym. interface IArayuzYeni { void Metod1(String metin); } interface IArayuzDiger { int Metod1(String a); void Metod1(String metin, int deger); } class UygulayanSinif implements IArayuzYeni, IArayuzDiger { public void Metod1(String yazi)
167

{ } public void Metod1(String yazi, int sayi) { } public int Metod1(String metin) { return 3; } } public class Uygulama2 { } Burada iki arayz ierisinde Metod1 isminde 3 farkl metod bildirimi yaplmtr. lk aamada, bu arayzlerin ikisinide birlikte uygulayan snfmz iin bir sorun kmayaca dnlebilir. Ancak metodlarn bu ekilde ar yklenmelerinde metod imzalarnn nemli olduunu hatrlamakta fayda var. yleki, burada her iki arayzde de ayr ayr tanmlanm void Metod1(String metin); int Metod1(String a); metod bildirimleri farkl arayzlerde olasalar dahi, ayn snfa uygulandklarndan ar yklenmi metodlarn sahip olacaklar karakteristikleri tamalar gerkiyor. Nitekim burada bu metodlarn ar yklenmesini engelleyen bir olgu var ki buda metodlarn imzalar. Metod isimleri ve parametreler tamamen ayn, fakat metodlarn geri dn deerinin farkl olmasnn metodun imzasnda etkin rol oynamamas, aadaki derleme zaman hatalarnn olumasna neden olmakta.

168

Gelelim arayzler ile ilgili dier bir noktaya. Arayzleri oluturduumuzda, bunlarn sisteme birer class dosyas olarak kaydedildiini grrz. Dolaysyla arayzlerin birer snf olduunu dnebiliriz. Bununla birlikte, snflarda olduu gibi arayzleri de birbirlerinden tretebilir ve bylece arayzler arasnda kaltmn gereklemesini salayabiliriz. rnein, interface ITemel { void Temel(); } interface ITureyen1 extends ITemel { void Tureyen1(); } interface ITureyen2 extends ITureyen1 { void Tureyen2(); } class deneme implements ITureyen2 { public void Temel() { System.out.println("Temel arayuzun metodunu uyguladim...");
169

} public void Tureyen1() { System.out.println("Tureyen1 arayuzunun metodunu uyguladim..."); } public void Tureyen2() { System.out.println("Tureyen2 arayuzunun metodunu uyguladim..."); } } public class Uygulama3 { public static void main(String[] args) { deneme d=new deneme(); d.Temel(); d.Tureyen1(); d.Tureyen2(); } } Bu rnekte, deneme isimli snf sadece ITureyen2 arayzn uyguluyor. Ancak bu arayz kaltm yolu ile, IArayuz1 interfaceinden, IArayuz1 ise, ITemel arayznden tretilmi durumda. Bu nedenle, deneme snfnn tm bu arayzlerdeki metodlar override etmesi gerekiyor. Olay daha fazla dramatize etmeden ematizme etmenin daha faydal olacan dnerek aadaki umlvari grafii hazrladm.

170

Kaltmn arayzlere nasl uygulandnda grdkten sonra aklma soyut snflara arayzlerin uygulanmas nasl olur diye bir soru geldi. Biliyordumki arayzleri bir snfa uyguladmda, bildirilen metodlar override etmeliyim. Soyut snflar arayz bildirimindeki gibi metod bildirimleri dnda i yapan metodlarda ierebiliyordu. Peki o halde, bir arayz bir soyut snfa uyguladmda, arayzdeki metod bildirimlerini bu soyut snfta override etmem gerekir miydi? Bunu anlamann en iyi yolu arayz, soyut snflara uygularken metodlar override
171

etmeyi ihmal etmeye almakt. Aynen aadaki kodlarda olduu gibi. interface ITemel { void Temel(); } interface ITureyen1 extends ITemel { void Tureyen1(); } interface ITureyen2 extends ITureyen1 { void Tureyen2(); } abstract class Soyut implements ITureyen1 { abstract public void Metod(); } Yukardaki uygulamaya Soyut isminde bir abstract snf ekledim. Bu snfa ITureyen1 arayzn uyguladm. Uygulamay derlediimde baarl bir ekilde derlendiini grdm. Demek ki bir arayz bir soyut snfa uygularsam, arayzdeki metod bildirimlerini bu soyut snf iinde override etmem gerekmiyormu. Tabi elbetteki, Soyut isimli abstract snftan tretilen bir snfn hem bu soyut snftaki hemde bu soyut snfn uygulad arayzlerdeki metodlarn hepsini override etmesi gerektiini sylememede gerek yok. Arayzler ile ilgili en ok houma giden zelliklerden biriside i ie gemi (nested) arayz tanmlamalarnn yaplabilmesi. Yani bir arayz tanm baka bir arayz tanmn ve hatta baka arayz tanmlamalarn bnyesinde barndrabilmekte. Tek dikkat etmem gereken nokta, dahili arayzlerin protected, private yada friendly eriim belirleyicilerine sahip olamamalar. rnein, aadaki kodlar ile, iiie gemi arayzlerin bildirimi yaplyor.
172

interface IGenel { interface IBilgi { void PersonelKunye(int ID); } interface IUcretlendirme { int MaasHesapla(int saatUcret,int saat); } interface IDepartman { String Kod(String departmanAd); } } class Personel implements IGenel.IBilgi { public void PersonelKunye(int PerID) { System.out.println("Personel NO "+PerID); } } public class Program { public static void main(String[] args) { Personel p=new Personel(); p.PersonelKunye(45855); } }

173

Burada grld gibi IGenel arayz 3 adet arayz iermektedir. Snfmza bu arayzlerden sadece IBilgi isimli arayz uygulamak iin aadaki sz dizimini kullandm. Dolaysyla Personel snfn iin, IGenel arayz iindeki IBilgi arayznn uygulanacan belirtmi oldum. class Personel implements IGenel.IBilgi Burada olan eyi ekil itibariyle ifade etmek gerekirse aadaki grafii gsterebilirim.

Elbette IGenel arayznn tamamnda uygulayabiliriz. Bu durumda, IGenel arayz ierisinde yer alan tm arayzlerin ierdii metod bildirimlerinin, ilgili snf tarafndan override edilmeleri gerekmektedir. ie gemi arayz tanmlamalar, birbirleriyle ilikili, ortak alamalara ve amalara ynelik arayzlerin bir at altnda toplanmasnda izlenebilecek etkili yollardan birisidir. Bu yap aslnda C# taki isim alanlarna veya javadaki paket kavramna benzer bir sistematikle iler.
174

Arayzler ile ilgili olarak kahvemizin syleyecei fazla bir ey yok aslnda. Arayzler faydaldr. Dahas gnlk uygulamalarmzda ok fazla bavuramadmz bu sistematik yaplar, zellikle birden fazla programcnn bir arada yer ald byk apl uygulamalarda nem kazanmakta ve snflarn oluturduu veri modellerine rehberlik yapmaktadr. Artk kafeinin etkisi giderek azalmaya ve gz kapaklarm kapanmaya balad. Ancak bu kahve molas ile birlikte ok ey rendiime inanyorum. Bakalm gelecek kahve molalarnda beni ne gibi srpriz konular bekliyor.

Blm 12: Dahili Snflar (Inner Classes) Bu hafta Java programlama dilinde kullanlan ok ilgin bir konuyu inceledim. Snflar ierisinde snflarn tanmlanmasndan tutunda, bir metod iinde snf tanmlanmas gibi ilgin kavramlar bnyesinde barndran bir konuydu bu. Inner Class (Dahili Snflar) kavram. Bu kahve molas akas ok elenceli geecee benziyor. Programatik olarak yani. Yoksa dardan birisi bana bakpta, yazdm rnek kodlardan sonra hafife gldm grse, sanyorum ki bu adam keileri karm der. Aslnda hepimiz yle deilmiyiz? Programclar doalar gerei hafif uuk adamlar olmak zorundadrlar. Eer kodlara bakp kendi kendinize glmek gibi bir hobiniz yoksa, hemen bir tane edinmenizi tavsiye ederim. Bir programcnn karizmasn gerekten nemli lde arttyor. Tabi glmek derken sinsi sinsi glp hafifede Platinyum Kadir Bey havas katacaksnz iin iine. Neyse muhabbeti brakp i yapmak sanrm daha hayrl olucaktr. Nedir bu dahili snflar? Ne i yaparlar? Neden kullanlrlar? Bu sorular ierisinde en zor olan belkide dahili snflara neden ihtiya duyduumuzdur. Doruyu sylemek gerekirse, bu ihtiyac anlayabilmek iin, kaynaklarda kullanlan rnekleri bir hayli kurcalamam gerekti. lk bata dahili snflarn, snflar normal kullanm alanlar haricinde farkl blgelerde kullanmak iin var olduklarn syleyebilirim. Her zaman iin uygulamalarmda u ana kadar, snflar hep ayr birer veri yaps olarak tanmladm. Ancak aadaki ekilde grlen dahili

175

snf tipleri ile, bir snf baka bir snf blou iinde tanmlamak, bir metod blou iinde tanmlamak mmkn.

zetle dahili snflarn, snf tanmlamalar ierisinde tanmlanan snflar olarak dnebiliriz. lk nce ye snflar incelemeye karar verdim. nk kaynaklar zellikle bu konuya olduka fazla yer ayrmt. ye snflar anlayabilmenin en iyi yolu basit bir rnee uygulamaktan geiyordu. Yapabileceim en basit rnek, bir snf tanmlamas iine bir ka snf tanmlamas eklemekti. Bu amala aadaki gibi bir snf tanmlamas oluturdum. public class DahiliSiniflar { class UyeSinif_1 { } class UyeSinif_2 { } class UyeSinif_3 { } public static void main(String[] args)

176

{ } } Yukardaki uygulamay derlediimde herhangibir hata mesaj ile karlamadm. Yani DahiliSiniflar snfm iindeki dier snflar iin derleyici bana ses kartmamt. te burada yaptm i, aslnda bir snf ierisine, bu snfn kapslledii ye Snf (Member Class) lar eklemekti. Bir baka deyile aslnda aada ekilsel olarak ifade edebildiimi dndm ilemi gerekletirmitim.

Her ey iyiydi gzeldi de, acaba bu ye snflar nasl kullanabilirdim. ncelikle, ye snflara i yapacak metodlar eklemeliydim. Bu amala kodlar aadaki gibi dzenledim. in kritik noktas, ye snf nesnelerinin, bu ye snflar ieren snfa ait main metodu ierisinde nasl rneklendirildikleriydi. public class DahiliSiniflar { class UyeSinif_1 { void Yaz() { System.out.println("UyeSinif_1 Yaz Metodu..."); }

177

} class UyeSinif_2 { void Alan(double en, double boy) { double alan=en*boy; System.out.println("Alan "+alan); } } class UyeSinif_3 { int Topla(int baslangic, int bitis) { int toplamDeger=0; for(int i=baslangic;i<=bitis;i++) { toplamDeger+=i; } return toplamDeger; } } public static void main(String[] args) { DahiliSiniflar.UyeSinif_1 uye1=new DahiliSiniflar().new UyeSinif_1(); uye1.Yaz(); DahiliSiniflar.UyeSinif_2 uye2=new DahiliSiniflar().new UyeSinif_2(); uye2.Alan(5,10); DahiliSiniflar.UyeSinif_3 uye3=new DahiliSiniflar().new UyeSinif_3(); int sonuc=uye3.Topla(5,10); System.out.println("Aralik degerleri toplami "+sonuc); }

178

Burada nemli olan nokta, ye snflara ait bir nesne rnei yaratabilmek iin, nce ye snf kapsayan snfa ait bir nesnenin oluturulmak zorunda olduu. Yani, DahiliSiniflar.UyeSinif_1 uye1=new DahiliSiniflar().new UyeSinif_1(); satrlar ile, nce DahiliSiniflar snfndan bir nesne oluturuluyor ve ardndan bu snfn ye snf olan dahili UyeSinif_1 snfna ait bir nesne rnei oluturuluyor. Evet sz dizimi olduka garip, bunu bende kabul ediyorum. Ancak, olay mantk boyutlar erevesinde son derece gzel aklyor. Tabi burada kafama taklan en nemli sorun u. Her ye snf nesnesi rnei iin, ye snf ieren snf rneini oluturmak zorundamym. Bu durumda n kadar ye snf ieren bir snf uygulamasnda, her bir ye snf iin bellekte gereksiz yer igali olmyacakm? Yazk deilmi gzelim sistem kaynaklarn harcamaya? Neyseki bu durumun zmn ksa srede kaynaklardan tedarik ettim. zm ilk bata, ye snflar ieren snfa ait bir nesne rneini oluturmak ve daha sonra ye snflara ait nesne rnekleri iin, oluturulan bu snf rneinin referansn kullanmakt. Yani u ekilde, public static void main(String[] args) { DahiliSiniflar ds=new DahiliSiniflar(); DahiliSiniflar.UyeSinif_1 uye1=ds.new UyeSinif_1();

179

uye1.Yaz(); DahiliSiniflar.UyeSinif_2 uye2=ds.new UyeSinif_2(); uye2.Alan(5,10); DahiliSiniflar.UyeSinif_3 uye3=ds.new UyeSinif_3(); int sonuc=uye3.Topla(5,10); System.out.println("Aralik degerleri toplami "+sonuc); } imdi kafam kurcalayan nokta, ye snf yapclar ile, ye snflar ieren snf yapcs arasndaki ilikinin ieriiydi. Sonuta ya kapsl snfn tek bir nesne rneine bavurarak, ye snf nesneleri oluturuyor yada her ye snf nesnesi iin birer kapsl snf nesnesi oluturuluyordu. Her ne ekilde olursa olsun, kapsl snfn yapcsnnda, ye snfn yapcsnnda altrlaca kesindi. Peki sralama nasl olucakt? Elbette burada kaltmda yapclarn nasl alt gz nne alnabilirdi. Kaltma gre, en st ata snfn yapcs ilk olarak arlacak, daha sonra hiyeraride aaya doru inilerek dier yapclar srasyla ileyecekti. Bu ilevi izleyebilmek amacyla aadaki rnei gelitirdim.( Her zamanki gibi i yapmayan ama amac kavramaya ynelik bir rnek...) public class Uygulama { class Uye_1 { Uye_1() { System.out.println("Uye_1 Sinifi Yapicisi..."); } class Uye_1_AltUye { Uye_1_AltUye() { System.out.println("Uye_1 Sinifinin Uye Sinifinin

180

Yapicisi..."); } } } Uygulama() { System.out.println("Kapsul Sinifi Yapicisi..."); } public static void main(String[] args) { Uygulama.Uye_1.Uye_1_AltUye nesne=new Uygulama().new Uye_1().new Uye_1_AltUye(); } }

Her ne kadar, en alttaki ye snfa ait nesneye oluturmak uzun ve zahmetli bir yol olarak gzksede sonu itibariyle amacma ulamtm. Yapclar tahmin ettiim gibi kapslleyen snftan altrlmaya balamt. Zaten bu, Uye_1_AltUye ye snfna ait nesnesnin oluturulmasndan nce dier st snf nesnelerinin oluturulma zorunluluunun bir sonucuydu. ye snflar ile ilgili bir dier ilgin nokta, ye snflarnda public ve friendly dnda, protected ve private gibi eriim belirleyicilerinin kullanlabilmesiydi. Normal artlar altnda, bir snf private yada protected eriim belirleyicileri ile tanmlamaya almak olanakszd. Oysaki ye snflarda durum farklyd. rnein bir ye snf private yaparak, kapsl snf dndaki dier snflarca kullanlmas engellenebilirdi. Nasl m? te rnei.

181

class DahiliSiniflar { public class UyeSinif_1 { void Yaz() { System.out.println("UyeSinif_1 Yaz Metodu..."); } } protected class UyeSinif_2 { void Alan(double en, double boy) { double alan=en*boy; System.out.println("Alan "+alan); } } private class UyeSinif_3 { int Topla(int baslangic, int bitis) { int toplamDeger=0; for(int i=baslangic;i<=bitis;i++) { toplamDeger+=i; } return toplamDeger;

} }

class UyeSinif_4 { UyeSinif_4() { System.out.println("UyeSinif_4 yapicisi"); } }

182

} public class Uygulama2 { public static void main(String[] args) { DahiliSiniflar ds=new DahiliSiniflar(); DahiliSiniflar.UyeSinif_1 uye1=ds.new UyeSinif_1(); uye1.Yaz(); DahiliSiniflar.UyeSinif_2 uye2=ds.new UyeSinif_2(); uye2.Alan(5,10); DahiliSiniflar.UyeSinif_3 uye3=ds.new UyeSinif_3(); int sonuc=uye3.Topla(5,10); System.out.println("Aralik degerleri toplami "+sonuc); DahiliSiniflar.UyeSinif_4 uye4=ds.new UyeSinif_4(); } }

Bu rnein bukadar uzun olduuna bakmamak lazm. Odaklanlmas gereken nokta, private ye snfn, tanmland kapsl snf dndaki bir snf ierisinde rneklendirilmeye allmasdr. Uygulamay derlediimde aadaki hata mesajlarn anladm.

Sonu gayet ak ve netti. Private tanmlanm bir ye snfa, tanmland kapsl snf dndan eriememitim. Ancak bu
183

kstlama ye snfa, tanmland kapsl snf iindeki baka ye snflar tarafndan eriilemiyecei anlamna gelmemekteydi. Dolaysyla, private ye snfa ait nesne rneini, baka bir ye snf iinde aada olduu gibi kullanabilirdim. Tek art yelerin, ayn kapsl snf iinde tanmlanm olmalaryd. class DahiliSiniflar { ... private class UyeSinif_3 { int Topla(int baslangic, int bitis) { int toplamDeger=0; for(int i=baslangic;i<=bitis;i++) { toplamDeger+=i; } return toplamDeger;

} }

class UyeSinif_4 { UyeSinif_4() { DahiliSiniflar.UyeSinif_3 uye3=new DahiliSiniflar().new UyeSinif_3(); int sonuc=uye3.Topla(5,10); System.out.println("Aralik degerleri toplami "+sonuc); } } } public class Uygulama2 { public static void main(String[] args) { ...

184

} }

DahiliSiniflar.UyeSinif_4 uye4=ds.new UyeSinif_4();

Artk Bonus Plusa gemenin vakti gelmiti. Vitesi arttrp konuda ilerlemeye devam etmeliydim. ye snflara burada nokta koyup dier dahili snflar incelemem gerektii dncesindeydim. Ancak yapamadm. ncelemem gereken bir konu daha olduunu farkettim. Static ye snflar. Nasl ki static metodlar altrmak iin nesne rneklerine gerek yoksa, static ye snflar oluturmak iinde, kapsl snfn nesne rneini oluturmaya gerek yoktur diye dndm ilk olarak. Acaba durum byle miydi? lk nce static bir ye snf tanmlamakla ie baladm. Sonraki amacm bu static snfa ait bir nesne rneini oluturmakt. Bu nesne rneini ilk bata klasik ye snf rneklendirme tekniiyle oluturmaya altm. public class Uygulama { static class Static_Uye { Static_Uye() { System.out.println("Statik_Uye Sinifi Yapicisi..."); } } public static void main(String[] args) { Uygulama.Static_Uye uye=new Uygulama().new Static_Uye(); }

185

} Kod baarl bir ekilde derlenmiti. imdi main yordam iindeki nesne rneklendirme satrn aadaki gibi deitirdim. Static_Uye uye=new Static_Uye(); Kod yine baarl bir ekilde derlendi ve alt. ki teknik arasnda olduka nemli bir fark vard. kinci kullanmda bu ye snf static olarak tanmladm iin, kapsl snftan bir nesne oluturma zahmetine girmemitim. Dolaysyla kapsl snf iinde bu ye snf normal bir snf tretirmiesine rnekleyebilmitim. Peki durum kapsl snf dndaki snflar iin nasl ceyran edecekti. Bunun iin yapmam gereken basit bir rnek ile durumu aydnlatmaya almakt. class Deneme { static class Static_Uye { Static_Uye() { System.out.println("Statik_Uye Sinifi Yapicisi..."); } } } public class Uygulama { public static void main(String[] args) { Static_Uye uye=new Static_Uye(); } } Uygulamay karlatm. derlediimde aadaki hata mesajlar ile

186

zm gayet basitti. Statik snfa ait nesne rneini olutururken, statik snfn tanml olduu kapsl snfda kullanmalydm. Nasl ki, ite yle ki. Deneme.Static_Uye uye=new Deneme.Static_Uye(); Bu haliyle uygulama baarl bir ekilde derlendi. Ancak yine dikkat edilmesi gereken nokta, kapsl snfa ait bir nesne rneinin oluturulmam olmasyd. Bununla birlikte static yelerin, kapsl snftaki alanlara ve dier yelere eriiminde bir sorun olduu kaynaklarmda geiyordu. Bunu en gzel bir rnekle irdeleyebileceimi biliyordum. class Deneme { String alan="BURAK"; void Kimlik() { System.out.println("MERHABA... "+alan); } static class Static_Uye { Static_Uye() { System.out.println("Statik_Uye Sinifi Yapicisi..."); Kimlik(); }
187

public class Uygulama { public static void main(String[] args) { Deneme.Static_Uye uye=new Deneme.Static_Uye(); } } Bu uygulamay derlediimde aadaki hata mesajn aldm.

Bunun sebebini kaynaklar u ekilde aklyor. Static bir ye snfn, kaspl snf ile arasnda this ilikisi yoktur. Buradan kartabileceim sonu, static ye snfn kendi iinden, kapsl snftaki yelere (alanlar ve metodlar) eriemiyeceiydi. Nitekim, buradaki snfmz statik olmasayd, kapsl snftaki yelere eriebilirdi. Ancak durum kapsl snftaki yelerde statik olursa deimekteydi. Yani rnei aadaki ekilde gelitirdiimde, uygulama baarl bir ekilde derleniyordu. nk ye snf, kapsl snfn nesne rneine ihtiya duyulmadan kullanlabilecek static yelere erimekteydi. class Deneme { static String alan="BURAK"; static void Kimlik() { System.out.println("MERHABA... "+alan); }

188

static class Static_Uye { Static_Uye() { System.out.println("Statik_Uye Sinifi Yapicisi..."); Kimlik(); } } } Artk sra yerel snflar renmeye geldi sanyorum. Ama bu dahili snf tipine gemeden nce zellikle, ye snflarn genel kullanm amac zerinde durmakta fayda olacan dnyorum. ye snflar, oklu kaltmn gerekletirilmesine imkan salamaktadrlar. Nitekim, bir snf bir ka snftan birden tretmek mmkn deildir. Ancak bir snfa bir ka arayz uygulanarak oklu kaltm ksmide olsa snrl bir ekilde uygulanabilir. Bununla birlikte ye snflar ile oklu kaltm daha gvenli ve gl bir ekilde gerekletirilebilir. Bu amala gelitirdiim aadaki basit rnei incelemekte fayda var sanrm. class TemelSinif { void Yaz(double deger) { System.out.println("Sonuc "+deger); } } class AltTemel { double Alan(double en, double boy) { return (en*boy)/2; } } public class Program extends TemelSinif {

189

class Alt1 extends AltTemel { Alt1() { Yaz(Alan(20,2.5)); } } public static void main(String[] args) { Program.Alt1 nesne=new Program().new Alt1(); } }

Peki burada olan olay nedir? oklu kaltm nerede gizlidir? Bunu cevaplandrabilmenin en kolay yolu, uygulamadaki snflar arasndaki ilikiyi ematik olarak ifade edebilmektir. Bu amala, uml vari bir diagam gelitirmeye altm.

ekilde herey daha net. (.net deil berrak anlamnda...) Program snf ierisinde yer alan Alt1 ye snf, AltTemel isimli

190

snftan tretiliyor. Lakin, ye snfmzn bulunduu kapsl snf olan Program snfda, TemelSiniftan tretilmitir. Dolaysyla burada, Alt1 snf hem AltTemel, hemde TemelSinif snflarnn yelerine eriim hakkna kaltm gerei sahiptir. Zaten rnektede bunu irdelemeye altm. ye snf yapcs iinden, ye snfn iinde bulunduu kapsl snfn tredii temel snftaki metodu, ye snfn tredii snfa ait metodu parametre alacak ekilde ardm. te ok biimlilik denen olayn ye snflar ile gvenli bir biimde uygulanabilmesi. Sanyorumki artk dier dahili snflara geebilirim. Bu umutla kaynaklarma son kez bakp titreyen eller ile, umarm ye snflarn baka srprizleri yoktur diyerek sayfalarda ilerlemeye devam ettim. Ancak biliyorumki ye snflar ile ilgili ileride karma yeni eyler kacak. Bu java dilinin doasnda olan bir ey. Srekli srprizler yapyor bu lgn programlama dili. Giderek sevmeye mi baladm ne. Nihayet!!! Sonunda yerel snflara gelebildim. Yerel snflar, ye snflardan daha ilgin bir kavram. yleki, bir metodun iersinde kullanlmak zere snf bildirimleri gerekletirilebiliyor. Sadece metod olsa iyi. Yapclar iindede yerel snf tanmlamlar yaplabilmekte. Ancak burada nemli olan yerel snfn sadece tanmland metod blou ierisinde alyor olmas. Dolaysyla bu metod dndan bu snflara erimek mmkn deil. Neden byle bir gereksinimim olabilir sorusuna gelince, bu nmzdeki aylar boyunca kendi kendime soracam bir soru olarak kalcak sanyorum. Ama bu tarz sorulara verilen gzel bir cevabda grmezden gelemem. "Dilin kabiliyetlerini bilmemizi salar..." Bir bakalm yerel snflar neyin nesiymi. public class Aritmetik { static double Hesaplamalar(double a,double b) { class Alan { double en; double yukseklik;

191

Alan(double deger1,double deger2) { en=deger1; yukseklik=deger2; } public double Hesapla() { return (en*yukseklik)/2; } } Alan nesne=new Alan(a,b); return nesne.Hesapla(); } public static void main(String[] args) { double sonuc=Hesaplamalar(8,4); System.out.println(sonuc); } }

Olay son derece akt aslnda. Metod iinde bir yerel snf tanmlanm ve kullanlmt. te yerel snflarn z buydu. Yerel snflar, kullanldklar metod dnda ilevsel deildi. Bununla birlikte, bir yerel snf baka snflardan veya arayzlerden tretebilirdik. Yerel snflar ile ilgili nemli bir kstlamada, sadece friendly eriim belirleyicisine sahip olabilmesiydi. Yani ye snflarda olduu gibi tm eriim belirleyicilerini kullanlamyorlar. Zaten, sadece metod iinde geerli olmasnda bu durum bir nebze olsun aklyor.

192

Kahvem azaldka gecenin bu ge saatlerinde enerjimde azalmaya balad. Ancak ilemem gereken bir dahili snf eidi daha var. Bu dahili snf tr, isimsiz snflar. Akas bu snflarn kullanmn dndke biraz gldm kendimce. Nasl m? Haydi kahvemizden bir yudum daha alalm ve isimsiz snflar inceleyelim. interface Alan { public double Hesapla(); } public class Aritmetik2 { public static Alan Hesaplamalar(final double a,final double b) { return new Alan() { public double Hesapla() { return (a*b)/2; } };

public static void main(String[] args) { Alan a=Hesaplamalar(8,4); double sonuc=a.Hesapla(); System.out.println(sonuc); } } Neden gldm imdi daha iyi anlamsnzdr herhalde. Kodu kaynaklarmdaki rnekleri inceleyerek oluturdum. Sonrada, rneimin iinde, isimsiz snf aramaya baladm. te o anda bir glme krizi ald beni gitti. simsiz snf bulamyordum. Kod her zamankinden farklyd, hemde ok farklyd ancak ben isimsiz snf bir trl bulamyordum. Sonradan dikkatimi, Hesaplamalar isimli metodunun geri dn deerinin tr ekti.
193

Bu metod dn tipi olarak bir arayz nesnesi iaret etmekteydi. Bir arayz nesnesi geri dndrecekse eer, return anahtar kelimesinden sonra bu arayz uygulayan bir snf rneinin dnmesi gerektiini anlamtm. te isimsiz snfm oradayd. Hakikattende isimsiz bir snft. Ad yoktu ama an alm ban yryordu. Gzkmeyen kahraman gibiydi desem yeridir. return anahtar kelimesinden sonra, metodun dn tipi olan arayze ait bir snf oluturulmu ve iinde bir takm hesaplamalar yaptrlmt. Yani isimsiz snfm urasyd. return new Alan() { public double Hesapla() { return (a*b)/2; } }; Akas anlalmas ve kullanm olduka karmak bir yapda. Tam olarak kavrayabildiimi syleyemem. Ancak kaynaklarm zellikle ileride greceim, olay dinleyicileri (event listener) ile ilgili yerlerde sklkla kullanldn belirtiyor. En azndan imdilik, nasl kullanldn grdm. Zaman ilerledike bu kavramnda yerine oturaca kansndaym. Ancak imdi dinlenme zaman geldi diye dnyorum. Kahvemde bitti zaten.

Blm 13: stisnalar (Exceptions) Nesne ynelimli programlama dillerini zel klan yanlardan biriside salam olduklar istisna ynetim mekanizmalarnn eitliliidir. ou zaman, zellikle alma zamannda oluabilecek hatalarn glgesinden kurtulmak ve kullanc dostu projeler gelitirmek zorundayz. Bunu yaparken sadece doru kurallar ve algoritmalar yeterli olmayabilir. zellikle kullanc

194

etkileimli tasarmlarda, gelebilecek deiik ve vurdumduymaz taleplere kar hazrlkl olmak gerekir. Java dilinde olsun C# dilinde olsun, alma zamannda oluabilecek yada derleme zamannda olumas kesin bir takm hatalarn nne gemek amacyla istisna mekanizmalar kullanlmaktadr. Istisna mekanizlamalar u mehur herkesin duyduu hatta bildii try-catch-finally bloklarnn kullanld teknik ile salanyor. Kanmca, istisnalar anlayabilmenin en iyi yolu istisna frlatan ( ki bu terim throwing olarak geiyor ) bir uygulama gelitirmekten geiyor. Bu amala aadaki gibi ok basit bir uygulama tasarladm. Oluacak hata batan belliydi. Balk batan kokmutu. Ama neyseki keskin Jacobs aromal kahvem bu kokuyu bastryordu. Kalkpta, 10 elemanl bir dizinin 10nuci indeksine, bu dizinin 0 tabanl olduunu bile bile erimeye almak elbette bellekte byle bir yer ayrlmad iin hataya neden olucakt. Ama istisnalar ele almannda en kolay yolu byle basit bir rnekten geiyordu. public class Istisnalar { public static void main(String[] args) { int dizi[]=new int[10]; for(int i=0;i<10;i++) { dizi[i]=i*i; } System.out.println("Dizinin 10ncu elemani "+dizi[10]); System.out.println("Program sonu"); } } Bu uygulamay derleyip altrdmda aadaki gibi bir hata mesaj ile karlatm. Aslnda u ana kadarki kahve molalarmda, ou zaman hatalar ile karlamtm ve durumu dzeltmitim. Ancak bu kez meydana gelen bu hatann alma zamanndan nasl nleneceini ve uygulamann aniden sonlandrlmasnn nasl nne geileceini inceleyecektim.

195

Burada gerekleen en nemli ey, programn almas srasnda bir istisnann olumas ve sonlandrlmasdr. yleki, hatann meydana geldii satrdan sonraki program kodu ifadesi altrlmamtr. Yani, isteimiz dnda bir sonlandrlma gerekletirilmitir. Buda elbetteki istenmeyen bir durumdur. Ancak, istisna ynetim mekanizmas yardmyla bu kodun sorunsuz bir ekilde almasn ve istemsiz olarak aniden sonlandrlmasn engelleme ansna sahibim. Nasl olucak bu i? Elbetteki, C# dilinden gelen engin tecrbelerimi burada aynen deerlendirmek taraftarym. Kodu u ekilde dzenlersem istediimi elde edeceimi biliyordum. public class Istisnalar { public static void main(String[] args) { int dizi[]=new int[10]; for(int i=0;i<10;i++) { dizi[i]=i*i; } try { System.out.println("Dizinin 10ncu elemani "+dizi[10]); System.out.println("Program sonu"); } catch(ArrayIndexOutOfBoundsException e) { System.out.println("Bir hata olustu :"+e);

196

} }

Burada yaplan ilem aslnda try-catch bloklar ile hata takibinin en basit ekliydi. ematik olarak durum ancak aadaki kadar gzel bir ekilde dramatize edilebilirdi.

ki uygulamann sonucu arasnda ok fazla fark yokmu gibi grnyor ilk bata. Acaba gerekten byle mi? Elbette deil. Hereyden nce, bu kez hataya yol aan kod satrn try blou ierisine aldm. Dier yandan, oluacak olan hatay catch blounda yakalayarak kendi istediim kod satrnn devereye girmesini saladm. Bu olduka nemli. Nitekim, programn almasnn normalde sonlandrlaca yerde, catch bloundaki kodlarn devreye girmesini salam oldum. Bu, zellikle kullanc tarafl hatalarn deerlendirilmesinde olduka nemlidir. Ancak bu kod satrlarnda dikkat eken dier bir nokta, hatann bir nesne olarak tanmlanmas ve mesaj olarak gsterilmek iin kullanlmasdr.
197

catch(ArrayIndexOutOfBoundsException e) Aslnda burada yaplan, derleme zamannda try blou altnda meydana gelecek hatalarda, catch blounda belirtilen snf nesnesinin iaret ettii trden bir istisnann frlatlmasdr. Dolaysyla, burada belirtilen trden bir istisna oluursa ne olucaktr? Dizinin boyutu dndaki bir indekse eriilmesi sonucu oluturulan bu istisna nesnesi son derece spesifiktir. Ancak durum her zaman bu ekilde olmayabilir. Hereyden nce, bunu irdelemenin en iyi yolu ayn program kodunda farkl trden bir hatann meydana gelmesine yol amaya almak olmaldr. yleki, try { int a=1; int b=a/0; System.out.println("Dizinin 10ncu elemani "+dizi[10]); System.out.println("Program sonu"); } catch(ArrayIndexOutOfBoundsException e) { System.out.println("Bir hata olustu :"+e); } Bu haliyle kodlar altrdmda, aadaki hata mesaj ile uygulamann ahane bir ekilde sonlandrldn grdm. Ne yazdm catch blo devreye girmi nede uygulama istediim ekilde sonlanmt.

Sorun uydu. Catch blounda sadece, indeks tamasna ilikin bir istisna nesnesi yakalanm, ancak bu meydana gelmeden
198

nce, sfra blme hatasn frlatacak bir istisna olumutu. Yaplabilecek iki ey vard. lk aklma gelen ikinci bir catch blounu dahil etmekti. Aynen aada olduu gibi, try { int a=1; int b=a/0; System.out.println("Dizinin 10ncu elemani "+dizi[10]); System.out.println("Program sonu"); } catch(ArithmeticException e) { System.out.println("Sifira bolme hatasi :"); } catch(ArrayIndexOutOfBoundsException e) { System.out.println("Indeks tasma hatasi :"); }

Bylece aslnda birden fazla catch bloununda nasl kullanlabileceini grm olmutum. Dier yandan ikinci bir yol daha vard. Daha genel bir yol. Istisna ynetiminde, catch bloklarnda snf nesneleri tanmlanmaktayd. Bununla birlikte bu snflar Exception ismi ile bitiyorlard. Kendimi bir anda dedektif gibi hissettim desem yeridir. Bir sonuca varmak istiyorum ama ne? Yardmma geni bir java dkman yetiti. Burada grdm kadar ile, istisna snflar aslnda belli bir hiyerarik dzen ierisinde yer alyor ve birbirlerinden tretilen bir sistematik oluturuyorlard. Bu yapy zaten C# dilinden biliyordum. Ancak javada hiyerari biraz daha farklyd. Ancak ilk dikkatimi eken, uygulamann almas srasnda
199

yakalanabilecek dzeyde olan istisnalarn Exception snfndan tryor olmalaryd. Dolaysyla, yukardaki rnei tek bir catch blou ile aadaki gibi oluturulabilirdim. try { int a=1; int b=a/0; System.out.println("Dizinin 10ncu elemani "+dizi[10]); System.out.println("Program sonu"); } catch(Exception e) { System.out.println("Hata :" +e); } Bylece, aslnda try blounda, Exception snfndan treyen tm istisna snflar tarafndan temsil edilebilecek dzeyde oluacak hatalar yakalam oldum. Elbette byle bir durumda, oluacak hataya zel kod gelitirmemiz biraz daha zor olucaktr. nk hatay en genel seviyede yakaladk. Aslnda yeri gelimiken, java dilindeki istisna ynetimi sistemindende bahsetmek gerekli. Bu sistem aadaki gibi bir hiyerariye sahip.

200

Elbette hiyerari bu kadarla snrl deil. Yzlerce snf var. En nemli nokta, istisnalarn iki ana ksmda ele alnmas ve Throwable snfndan tremi olmalar. Throwable snf, java uygulamalarnn almas sonucu oluabilecek hatalar iki ana alt snfta kapsayarak deelendirmekte. Bu snflardan bir tanesi, try catch bloklar ile yakalanamyacak tipte olan ciddi sistem hatalarn bnyesinde barndrdan Error ata snf. Dieri ise, u ana kadarki asl rneklerde de incelediim, uygulamann almas srasnda yada derlenmesi srasnda , try catch teknii ile yakalanabilecek hatalar ieren Exception ata snf. rnein benim rnek uygulamalarda incelediim istisnalar, Exception snfndan treyen RuntimeException snfndan tremi istisnalard. Buradaki snflarn detayl ekilde bilinmesi elbette mmkn deil. Ancak uygulamalarmz gelitirirken ok iyi test etmeli ve ortaya kan istisna mesajlarn iyi deerlendirerek ele almalyz diye dnyorum. Gelelim istisna ileme ile ilgili dier ilgin noktaya. C# dilinde, try bloklar ierisinde, metod armlar kullanldnda, bu metod armlarnda meydana gelebilecek hatalar ilgili catch
201

bloklarnca yakalanbilmekteydi. Bakalm ayn durum java dili iinde geerli mi? Bu kez hataya neden olucak kodlar bir metod iinde aldm ve try blou iinden ardm. public class Istisnalar { public static void main(String[] args) { int dizi[]=new int[10]; for(int i=0;i<10;i++) { dizi[i]=i*i; } try { Metod(); System.out.println("Dizinin 10ncu elemani "+dizi[10]); System.out.println("Program sonu"); } catch(Exception e) { System.out.println("Hata : "+ e); } } public static void Metod() { int a=1; int b=a/0; } } Sonu olarak uygulama baarl bir ekilde derlendi ve alt. Demekki, hatay oluturacak olan kodlar baka metodlar ierisinde bulunsa dahi, dolaysyla uygulamann baka bir konumunda olsa dahi, try bloklarnca ele alnabilir ve frlatacaklar istisnalar yakalanabilir. stisna ilenmesi ile ilgili bir dier ilgin konuda, i ie gemi istisna bloklarnn
202

kullanmdr. ie gemi try bloklar ounlukla, hatalarn olutuklar yerlere gre farkl davranlarda bulunabilirler. Neden i ie gemi istisna bloklarn kullanrz pek fazla fikrim yok. Ancak dilin zenginliini bilmek asndan da olduka nemli. Bu amala nce aadaki gibi bir rnek gelitirdim. try { Metod(); try { System.out.println("Dizinin 10ncu elemani "+dizi[10]); System.out.println("Program sonu"); } catch(IndexOutOfBoundsException e) { System.out.println("Dizi tasmasi : "+ e); } } catch(ArithmeticException e) { System.out.println("Sifira Bolme : "+ e); }

Dikkatlice baktmda grdm ki, metodun iinde meydana gelen sfra blme hatas, iteki try blou almadan hemen nce meydana geldiinde, iteki try bloklar altrlmadan, dtaki catch blou altrlm ve program sonlandrlmt. O halde, bende try bloklar gibi deiik senaryolar denemeye karar verdim. Bu kez, Metod armn iteki try-catch bloundan sonraya aldm.

203

try { try { System.out.println("Dizinin 10ncu elemani "+dizi[10]); System.out.println("Program sonu"); } catch(IndexOutOfBoundsException e) { System.out.println("Dizi tasmasi : "+ e); } Metod(); } catch(ArithmeticException e) { System.out.println("Sifira Bolme : "+ e); }

Ne kadar ilgin. teki try blounda meydana gelen hata iteki catch blounda yakaland ama uygulama sonlanmadan dier kod satr devereye girdi ve dolaysyla Metod isimli metodum altrld. Burada oluan hatada dtaki catch blounu ilgilendirdiinden, dtaki catch blouda devreye girdi ve her iki hatada yakalandktan sonra uygulama sonland. Derken aklma yle bir senaryo daha geldi. teki try blounda yakalanamyacak cinsten bir hata olusa ve bu hatay yakalayacak catch dtaki olsa, bu hata yakalanr myd? Bir baka deyile acaba, iteki catch blounca yakalanamyacak hata, dtaki catch blounda deerlendirilmeye alnr myd yoksa program sonlanr myd? Byk bir merak iinde hemen aadaki kodlar yazdm. Aklma gelen ilk ey istisna snf

204

nesnelerinin yerlerini deitirmek oldu. Ne kadarda yaratc deil mi :) try { try { System.out.println("Dizinin 10ncu elemani "+dizi[10]); System.out.println("Program sonu"); } catch(ArithmeticException e) { System.out.println(e); } Metod(); } catch(IndexOutOfBoundsException e) { System.out.println(e); }

Evet imdi unu bir incelemekte fayda var. teki try blounda meydana gelicek olan hatay, iteki catch blounun yakalayamyaca kesindi. Bu durumda java alma zamannda, dtaki catch blouna geerek, iteki try blounda oluan hatay burada aramaya karar verdi. Buradada buldu. Dolaysyla dtaki catch blounu altrarak, uygulamay bu noktada sonlandrd. Yani, iteki try blounda oluan hata dtaki catch blou tarafndan yakaland. ie gemi try-catch bloklarnda oluabilecek dier bir durum ise, herhalde catch bloklarnda oluabilecek hatalarn nasl
205

deerlendirilebilecei olabilirdi. yleki iteki catch blounda bir hata meydana geldiinde bu hatann dtaki catch blou tarafndan yakalanmas gerekirdi. Deneyip grmek lazmd. almak lazmd. Durumu en iyi ekilde deerlendirebilmek iin, her iki catch blounada ayn ncelikli bir istisna snf nesnesi eklemem gerektiini dndm. Bu nedenlede Exception snfn kullandm. try { try { System.out.println("Dizinin 10ncu elemani "+dizi[10]); System.out.println("Program sonu"); } catch(Exception e) { int a=1; int b=a/0; System.out.println("Icteki catch "+e); } } catch(Exception e) { System.out.println("Distaki catch "+e); }

Sonu beklediim gibi olmutu. teki catch blounda oluan hata dtaki catch blounca deerlendirilmeye alnmt. Aslnda try-catch bloklar ile ilgili u ana kadar kullanmadm bir anahtar kelime var imdi aklma geldi. O da finally anahtar

206

kelimesi. finally bloklar bir try-catch kurgusunda, hata olsada olmasada devreye giren yaplardr. rnein; try { Metod(); System.out.println("Dizinin 10ncu elemani "+dizi[10]); } catch(Exception e) { System.out.println(e); } finally { System.out.println("Program sonu"); } Burada try blou iinde oluacak olan hatann catch blounda yakalanaca kesindir. Ancak program catch bloundan sonra hemen sonlandrlmaz. Bu noktadan sonra finally blou devreye girer ve ierdii kodlar altrlr. Dolaysyla uygulamann kts aadaki gibi olucaktr.

stisna yakalama ile ilgili sylenebilecek yada dnlebilecek eyler sadece bunlarla snrl deil. rnein, beenmediimiz istisna snflar yerine kendi istisna snflarmz yazabiliriz. Son derece kolay olan bu ilemde, tek yapmamz gereken, istisna snfmz Exception snfndan tretmemizdir. Derken tabi aklma bir soru geldi. Her programcnn bir programlama dilini renirken hemen hemen her konuda sorduu bir soru. Neden bu kadar geni bir istisna snf hiyerarisi varken kendi istisnalarm yazmaya alaym ? Bunun tek nedeni bazen meydana gelen istisnann her eyi tam olarak aklayamamas
207

olabilirdi. Buna en gzel rnek SqlException istisna snfdr sanrm. Sql ile ilgili veri taban ilemlerinde oluabilecek sorgu hatalarndan tutunda, balantda oluabilecek hatalara kadar pek ok hatay temsil eder. Ancak bize hata ile ilgili detayl yada spesifik bilgiler sunmaz. Byle bir durumda kendi istisna snfmz yazma ihtiyac duyabiliriz. Bu konu aslnda geni bir konu ve sanrm veri tabanlarnn java dilinde kullanlmas ile ilgili kahve molalarnda inceleyeceim.

Blm 14: 7 Yl Sonra Applet Yllar nce ben niversitede renciyken (sanrm 1996 veya 1997 ylyd) deerli bir snf arkadam ziyarete gitmitim. Kendisi bilgisayar teknolojilerine son derece ilgili birisiydi ve bu anlamda ortak pek ok ynmz vard. O yllarda ikimizde, zellikle grsel programlamaya ynelik yazlm gelitirme ortamlarna ilgi duyuyorduk. O gnk ziyaretimde, dostumun elinde o gne kadar grdm en kaln kitap duruyordu. Sanrm o zamanlar gzme ok byk gzkmt. yleki o gne dek hi 900 sayfalk bir bilgisayar kitab grmemitim. Oysaki imdi o 900 sayfalk kitaplar arar oldum. En son altm bilgisayar kitab 1500 sayfaya yakn olunca, insan ister istemez zlyor. Neyse szn ksas, arkadamn elinde tuttuu kitap, ingilizce bir bilgisayar kitabyd ve Java diye bir eyden bahsediyordu. Oha falan oldum yani der gibi arkadamn gzlerine baktm. nk ilk aklma gelen StarWars serisindeki Java olmutu. Hemen ne demek istediimi anlad ve anlatmaya balad. Javann yeni bir programlama dili olduunu, C++n syntaxna ok benzer yer yer ayn yazmlar kullandn ancak iin iinde platform bamszln yer aldn syledi. O zamanlar bende pek ok kii gibi platform bamsz ksmna geldiinde, hafif bir tebessmle hadi canm demitim. ok gemeden bana kitabn ilk kaynak uygulamsndan gelitirdii kodu gsterdi. Burada komik bir izgi karakter (krmz burunlu) bir internet explorer penceresinde bir oraya bir oraya taklalar atyordu. Bu nedir diye sorduumda bana bunun bir Applet olduunu ve browsern

208

zerinde dinamik olarak yerel makinede altn syledi. O zamanlar elbetteki browser zerinde alan dinamik uygulamalara hi aina deildim. Java dilini renmeye baladmda, gnn birinde bu deerli arkadam hatrlayacam ve kulaklarn nlatacam biliyordum. Artk o zamanlar syledikleri imdi kulama daha teknik olarak geliyor. Eeee ne demiler "ge olsunda g olmasn". e appletlerin ne olduunu kavramak ile balamam gerekiyordu. Daha sonraki kahve molalarmda ise appletleri kullanc ile dinamik olarak etkileime sokmaya alacaktm. Ama nce teknik bilgi ve basit kodlara ihtiyacm vard. Tabiki appletin basit bir tanmndan sonra. Bir applet, istemci uygulamada yada baka bir deyile yerel makinede, Java Virtual Machinee sahip herhangibir taraycda (browser) derlenerek altrlan dinamik bir java programcndan baka bir ey deildir. Appletleri normal java programlar yazar gibi java dosyalar olarak yazar ve javac arac ile class olarak byte-codea eviririz. Tek fark, bu program paralarnn, taraycdan talep edilmeleri halinde, taraycnn sahip olduu JVM sayesinde derlenerek bu taraycnn yer ald yerel makinede dinamik olarak alacak olmalardr. Dolaysyla normal java byte kodlar gibi, bu kodlarda altrldklarnda derlenirler. Ancak alma sistemleri, ierdikleri olay yaplar konsol veya grsel arabirime sahip java uygulamalarndan biraz daha farkldr. Hereyden nce, taraycda altklar iin, belirli bir alan ierisinde izilebilirler yada kullanlabilirler. Bununla birlikte dinamik almaya msait olduklar iin aadaki olaylar gerekletirmelerine, yerel makinelerin gvenlii asndan izin verilmez. Appletlere zg Kstlamalar Yerel makineden (altklar makine) dosya kopyalayamazlar. Dosya silemezler. Dosya aamazlar veya oluturamazlar. ndirildikleri sunucudan baka bir
209

sunucu ile herhangibir a balants kuramazlar. ndirildikleri bilgisyarda baka programlar altramazlar. Dosya sistemine eriemezler veya okuyamazlar. Appletlerin almas ile ilgili olarak en dikkat ekici nokta, arldklar sunucudan istemci bilgisayarn taraycsna indirilmeleridir. Nitekim, bu ilemin gerekletirilmesi iin, applete ait class dosyasnn bir ekilde html kodu ierisine gmlmesi gerekecektir. Bunun nasl yapldn grmek iin ncelikle bir applet gelitirmek gerektii kansndaym. Ne kadar basit olursa olsun en azndan nasl altn grmem gerekiyor. Kaynaklarm inceledikten sonra, aadaki gibi bir rnek java dosyasn oluturdum. import java.awt.*; import java.applet.Applet; public class IlkApplet extends Applet { public void Paint(Graphics g) { g.drawString("Yihuuu",50,50); } } Burada oluturduum java dosyasn javac ile derlediimde herhangibir sorun ile karlamadm. Peki ama kodum ne yapyordu? Hereyden nce ilk dikkatimi eken, kullanlmak zere eklediim awt ve applet paketleriydi. Awt paketini ileride detayl incelemeyi dnyordum zaten. Ancak yinede n bilgiye ihtiyacm vard. Awt paketi ierisinde, java ile kullanabileceimiz grsel arayzlere ait nesneler iin bir ok snf bulunuyordu. Appletlerde sonu itibariyle, tarayc penceresinde alacaklarndan, kullanclar ile grsel iletiim salamamza yarayacak buton,textbox gibi nesneler ierebilirdi. te bu amala awt paketi vard. Geri kullandmz bir nesne

210

yok gibi gzkebilir ancak, Graphics snf awt paketi ierisinde yer alan ve appletin alt alan ierisine bir eyler izmek iin (rnekte olduu gibi yaz yazmak iin mesela) kullanlan bir snftr. Dier nemli bir kavramda, snfn Applet snfndan tretilmi olmasyd. Bu, yazlan java snfnn bir applet olarak deerlendirileceini belirtmekteydi. Dolaysyla applet snfndan bir takm zellikleri kaltmsal olarak alacamz kesindi. Gelelim, Paint metoduna. te iin en can alc noktas burasyd. Bu metod, tarayc pencersinde, appletin alt alana bireyler izmek iin kullanlyordu. Daha dorusu applet, snrlar ile birlikte tarayc penceresinde izilmeye baladnda alyordu. Artk, deerli dostumun tarihi java kitabndaki krmz burunlu kahramann nasl taklalar attn daha iyi anlamaya balamtm. O zamanlar izgi filim gibi gelmiti. Ancak imdi gerein ta kendisi karmdayd. Peki imdi ne olacak? Bir ekilde yazdm appleti test etmem gerekiyor. lk aklma gelen ancak denemek istemediim eyi deneyerek ie baladm. yleki,

Byle bireyin bama gelecei kesindi diyebilirim. Elbetteki appletin alma sistemine bakldnda farkl ekilde uygulanmalar gerekirdi. Her eyden nce, bu applet bir taraycya indirilecek ve oradaki JVM tarafndan derlenecekti. Bunu test etmenin iki yolu vard. Birincisi bir applet tag ile bu snf bir html sayfasna koymak yada Applet Viewer aracn kullanmakt. lk nce applet tagn aadaki gibi denedim. Bunun iin applet snfm ile ayn klasrde olan bir html sayfas hazrladm. <html>

211

<head> <meta http-equiv="Content-Language" content="tr"> <meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> <title>New Page 1</title> </head> <body> <APPLET CODE="IlkApplet.class" WIDTH="500" HEIGHT="200"> </APPLET> </body> </html> Applet tag iinde en nemli ksm CODE anahtar kelimesinin olduu ksm idi. Burada, belirtilen 500 piksel genilik ve 200 piksel yksekliindeki alanda hangi applet snfnn altrlacan belirtiyorduk. imdi oluturduum bu html sayfasn taraycda atm. Ancak hi beklemediim aadaki sonucu elde ettim.

500 piksele 200 piksellik bir alan almt. Ancak yazmak istediim yazy grememitim. Bunun tek nedeni olabilirdi. JVM, ya snf dosyasn derlememiti yada appet snfn tarayc penceresine indirememitim. Tabi bir dier ihtimalde taraycnn zelliklede Microsoft Internet Explorer olduu iin, JVM

212

desteinin kaldrlm olabileceiydi. Aklma ilk gelen en gncel java plug-in indirmek oldu. Ancak daha ncesinde en azndan yazdm appletin doru olup olmadndan emin olmalydm. Neyseki, javann appletviewer arac yardmma yetiti. Komut satrnda aadaki satr ile appletimin almasnn sonucunu grdm. Applet Viewer program, yazlm olan appletlerin tarayc penceresine ihtiya duyulmadan altrlabilmelerini salyordu.

Evet appletim almt. Applet viewer bir appleti test etmek iin ideal bir yoldu. Ama kafam halen daha internet explorer taraycsnda neden almadndayd. Hemen internete girdim ve java plug-in iin en gncel srm aradm. http://java.sun.com/products/plugin/reference/codesamples/in dex.html Bu adreste rnek java appletleri vard. En son srme ait olanlardan bir tanesini altrmak istediimde, JVM iin gerekli srm yklemek isteyip istemediimi sordu. Tabiki bunu istiyordum. Hemen ykledim. Hemen derken yklemek biraz zaman ald tabiki ama sonua herey yoluna girdi. Bu ilemin

213

sonucunda html sayfam taraycdan tekrar altrdmda aadaki sonucu elde ettim.

Appletim html sayfasndan da almt. Harika. Bu appletin ardndan daha gelimi bir applet yazmam gerektiini dnyordum ki karma appletlerin altrldnda gerekleen olaylarn bir listesi geliverdi. Bir applet altrldnda aslnda aadaki olaylar gerekletiriliyordu.

Grld gibi bir appletin almas srasnda ileyen 4 temel olay var. Bu metodlardan ilki init metodu, applet tarayc bilgisayara indirildiinde altrlmaktadr. Start metodundaki kod satrlar ise applet almaya baladnda tetiklenir. Stop metodunda yer alan kodlar, appletin bulunduu sayfadan baka bir sayfaya atlandnda dolaysyla applet kapatldnda altrlr. Destroy metodundaki kodlar ise, tarayc penceresi kapatld srada altrlr. Elbette birde paint metodumuz var. Bu metod ile, appletin ierisinde tarayc penceresinde

214

belirlenen alanlarda bireyler izdirmek iin kullanacamz kodlar yer alr. Dier yandan, kullanc ile etkiim halinde olan appletlerde, kullancnn tepkisine gre applet zerinde yaplacak yeni izimler repaint isimli metodlar ierisinde gerekletirilir. imdi bana bu metodlarn bir appletin almas srasnda nerelerde devreye girdiini gsterecek bir rnek gerekliydi. Hemde appleti biraz daha gelitirmi olurdum. Bu amala kaynaklarmdan edindiim bilgiler nda aadaki gibi bir java applet snf oluturdum. import java.awt.*; import java.applet.Applet; public class IlkApplet extends Applet { public void init() { setBackground(Color.yellow); System.out.println("Applet yuklendi..."); } public void paint(Graphics g) { g.drawString("paint",50,50); } public void start() { System.out.println("Applet calistirildi..."); } public void stop() { System.out.println("Applet sonlandirildi..."); } } Bu applet snfn derleyip appletviewer ile altrdmda ilk olarak aadaki grnty elde ettim.

215

Grld gibi ilk nce init metodu devreye girdi. Ardndan appletin start metodunda yer alan kodlar altrld ve sonrasnda ise paint metodundaki kodlar devreye girdi. alan bu appleti Appet Viewern Applet mensnden stop komutu ile durdurduumda ise aadaki ekran grntsn elde ettim.

Bu kez appletin stop metodundaki kodlar devreye girmiti ve appletin almasda sona ermiti. Appletlerin alma sistemini anladktan, yaam sresi boyunca altraca metodlar ve gerekleen olaylar inceledikten ve bir buuk satrlk applet kodu yazdktan sonra, daha ie yarar bir rnek grmek istiyordum. Hatta yazmak istiyordum. Ancak ie yaramasa bile beni etkilyebilecek bir rnek bulmann daha iyi olaca kansna vardm. Bu amala Sunn sitesinden rnek appletlere baktm. http://java.sun.com/products/plugin/1.5.0/demos/plugin/apple ts/MoleculeViewer/example2.html

216

Bu adreste yer alan appleti gzelce bir inceledim. Applette yaplmas gereken, mousea basl tutup ekli herhangibir yne doru srklemeye almakt. Akas bu applete baknca ve u an java dilinde bulunduum yeri dnnce kendi kendime yle dedim. "OOOOK ALIMAM LAZIMMM. OOOOKK!!!". Neyseki nmzdeki hafta boyunca, java appletlerinde awt snfna ait GUI nesnelerini kullanarak kullanclar ile nasl dinamik etkileime geileceini renmeye alacam. Artk dinlenmenin tam zaman. Kahvemde bitmi zaten.

Blm 15: Appletler ile Grsel Tasarm Geen hafta boyunca Applet lerin byl dnyasn daha ok kefedebilmek iin uratm durdum. Nitekim Applet leri daha etkin bir ekilde kullanabileceimi ve Appletlerin ok daha fazlasn sunduunu biliyordum. rnein, kullanclar ile dinamik etkileime geilmesini salayacak tarzda applet ler zerinde alabilirdim. Bu konuda aklma ilk gelen, bilgi giri formu ekran oldu. lk bata nereden balamam gerektiini bilmiyordum. Applet lerin alma mimarisinden haberim vard. Ancak, grsel eleri bu applet ler zerinde nasl oluturabilirdim? Dahada nemlisi, bu grsel nesnelerin, kullanc aktivitelerine cevap vermesini nasl programlayabilirdim? Bir baka deyile, grsel programlamann en nemli yaptalarndan birisi olan olay-gdml programlamay nasl gerekletirebilirdim? Tm bu sorularn cevaplarn bulmak maksadyla, hafta boyunca aratrmalarm srdrdm. Kilit nokta, Java dilinin Awt isimli (Abstract Windows Toolkit) paketiydi. Awt hem applet ler iin hemde ileride incelemeyi dndm normal GUI (Graphical User Interface) ler iin ortak nesne modellerini kapslleyen bir paketti. lk okuduumda bu paketin, Voltran n paralarndan birisi olduunu zannetmitim. Ancak salad imkanlar ile, Voltran n deil gvdesi tm benliini oluturabilirdim. in geyii bir yana, Awt paketi, java ile gelitirilen herhangibir GUI uygulamas iin gerekli olan tm grsel bileenleri salamaktayd. Hatta bu

217

bileenlerin her GUI uygulamasnda ayn tipte grnmesinede imkan tanyordu. zellikle Visual Studio.Net gibi grsel gelitirme ortamlarnda program arayzlerini (interface programlama deil, grsel tasarm anlamnda) tasarlamak son derece kolay. Ama ister .net platformunda olsun ister Java platformunda, nesne ynelimli dillerin doas gerei tm grsel bileenlerde aslnda birer snf modelinin rneklemelerinden baka bir ey deiller. Dolaysyla Awt paketi iindeki grsel bileenlerinde birer snf modeli olduunu belirtmekte yarar var. rnein, sayfalarda gsterebileceim butonlar Button snfna ait nesne rnekleri olacak. Sadece metin bilgisi tayan okuma amal Label bileenleri, Label snfna ait olacak. Yada Checkbox, TextField, TextArea, List, Image kontrolleri vs... Artk bir noktadan balamam gerektiini dnyordum. Kahvemden bir yudum aldm ve ilk nce nasl bir form tasarlamak istediime karar verdim. Bunu kat zerinde izmek kolayd ancak dijital ortama aktarmak zordu. Tasviri tam yapmak iin, Vs.Net editrn kullandm ve aadaki gibi bir formu, applet olarak tasarlamaya karar verdim.

Bu formu oluturmak iin hangi snflar kullanmam gerektiinede, JSDKdan baktm. u ana kadar her ey ak ve netti. imdi sra kodlama ksmna gelmiti. Aslnda ne yapmam gerektiini aka tahmin edebiliyordum. Applet, bileenleri zerinde barndracak yer olduuna gre, Applet i olutururken,
218

baka bir deyile applet i alr hale getitirken bu nesneleri ykleyebilirdim. Ancak bundan nce bu bileen nesnelerini oluturmam ve daha sonra bir ekilde Applete eklemem gerekiyordu. Felsefe ite bu kadar basitti. Felsefenin asl karaca noktann, bu bileen nesnelerinin olaylara cevap verebilecek ekilde kodlanmasnda oluacan da hissediyordum. Ancak ilk etapta, ncelikle appleti tasarlamam ve en azndan bileenleri applet zerinde sorunsuz bir ekilde gstermem gerektii kansndaydm. Hemen kollar svadm ve aadaki applet snfn oluturdum. import java.awt.*; import java.applet.Applet; public class Gui_1 extends Applet { public void init() { setBackground(Color.white); Label Label Label Label Label lbAd=new Label("Ad "); lbSoyad=new Label("Soyad "); lbAdres=new Label("Adres "); lbCinsiyet=new Label("Cinsiyet "); lbHobi=new Label("Hobi ");

TextField txtAd=new TextField(); TextField txtSoyad=new TextField(); TextArea txtAdres=new TextArea(2,5); CheckboxGroup cbCinsiyet=new CheckboxGroup(); Checkbox Checkbox Checkbox Checkbox cbInternet=new Checkbox("Internet"); cbMuzik=new Checkbox("Muzik"); cbSinema=new Checkbox("Sinema"); cbTiyatro=new Checkbox("Tiyatro");

Button btnYaz=new Button("Yaz");

219

} }

add(lbAd); add(txtAd); add(lbSoyad); add(txtSoyad); add(lbAdres); add(txtAdres); add(lbCinsiyet); add(new Checkbox("Erkek",cbCinsiyet,true)); add(new Checkbox("Kadin",cbCinsiyet,false)); add(lbHobi); add(cbInternet); add(cbMuzik); add(cbSinema); add(cbTiyatro); add(btnYaz);

Bu uzun kod dosyasnda temel olarak yaplan ilemler ok basitti. Hereyden nce nesneleri oluturabileceim en uygun yer init metoduydu. Burada her bir grsel bileen nesnesini teker teker new operatr ile oluturdum. Label bileenleri iin yapclarna Labeln balk metnini gnderdim. Ayn ilemi, CheckBox bileenleri ve Button bileeni iinde yaptm. Bylece ekrandaki Label, Checkbox ve Button bileenlerinin balklarnn ne olacanda otomatik olarak belirlemi oldum. Textfield bileenleri iinde parametreler girilebilir. zellikle Textfield n boyutunu belirlemek iin. Textarea bileeni iin ise, iki parametre girdim. lki satr saysn ikinciside stun saysnn gstermekte. Burada tek zel oluum radyo buton dediim CheckboxGroup bileenine ait. Bu bileene, yine Checkbox bileenleri ekleniyor. Yani bir CheckboxGroup bileeni birden fazla Checkbox kontorln ayn isim altnda gruplamak ve bylece bu bileenlerden sadece birisinin seili olmasn garanti etmek amacyla kullanlmakta. Bu bileen rneklerinin oluturulmasndan sonra tek yaptm add metodunu kullanarak bunlar Applet imin zerine eklemek oldu. Sonu mu? Aslnda gstermeye ekiniyorum. nk hite umduum gibi deil. Java bytecode dosyasnn class olarak

220

derledikten sonra bir html sayfasna <Applet tagn kullanarak ekledim. te sonu;

Ahhhh!!! Ahhh. Nerede gzelim Visual Studio.Net, Dreamweaver, Frontpage....yi gzel bileenleri oluturmutum, applet ede baarl bir ekilde eklemitim. Ama ya grsel tasarmn zerafeti ne olacak. Tam bu noktada ite aklp kalmtm. Kaynaklarma baktm benim yaptm bu estetik abidesini onlarda baarmlard. Kaynaklarm biraz daha aratrdktan sonra aslnda bu tasarm ve sayfaya yerletirme iinin baz kitaplarda blm olarak ilendiini grdm. Ancak u an iin bana en azndan zgaralanm bir grm hazrlayabileceim bir teknik gerekiyordu. Sonunda buldum ama... Geri bulana kadar bir ka fincan kahveyide bitirdim. in srr Olinde deil, tabiki sadakindeydi. Yani Layout teknii. Uyguladm teknik GridLayout teknii. Tek yapmam gereken tm kontrolleri eklemeden nce, Applet zerinde bir GridLayout yani zgara belirlemekti. Bunu gerekletirmek iin Appletin init metodunun en bana aadaki kod satrn ekledim. setLayout(new GridLayout(15,2)); Bu satr ile Appletin web sayfasnda kaplayaca alan, 15 satr ve 2 stuna blmtm. Artk GUI bileenleri srasyla yerleecekti. Ancak yinede sonu istediim gibi olmamt.

221

Hi yoktan iyidir diyerek devam etmek zorundaydm. Ancak Layout ayarlamalar ile ilgili olarak baka bir kahve molasnda daha derin bir aratrma yapmayda kafama koymutum. Olay yerinden uzaklarken, en azndan applet zerinde dinamik olarak grsel bileenlerin nasl eklendiini anlam ve bir ka bileenide renmitim. Asl merak ettiim, butona basldnda olmasn istediklerimi nasl yazacamd? Bunun iin, C# dilinde zellikle grsel programlamada delegeler ile yakn ilikide olan eventlar kullanlyordu. Java dilindede durum ok farkl deildi ancak anlalmas daha kolayd. Java dilindede, kullanc tepkilerini ele alabilmek iin delegasyon mant kullanlyordu. Bu modelin en nemli yan, grsel bileenlerinin kullanc tepkilerini alglayabilmelerini istediimiz Applet snfna, ActionListener arayzn uygulamamz gerekliliiydi. Kollar svadm ve ilk olarak, en basit haliyle, Button bileenime tklandnda meydana gelecek kodlar hazrladm.

222

import java.awt.*; import java.applet.Applet; import java.awt.event.*; public class Gui_1 extends Applet implements ActionListener { TextField txtAd; TextField txtSoyad; Button btnYaz; public void init() { setBackground(Color.white); Label Label Label Label Label lbAd=new Label("Ad "); lbSoyad=new Label("Soyad "); lbAdres=new Label("Adres "); lbCinsiyet=new Label("Cinsiyet "); lbHobi=new Label("Hobi ");

txtAd=new TextField(); txtSoyad=new TextField(); TextArea txtAdres=new TextArea(2,5); CheckboxGroup cbCinsiyet=new CheckboxGroup(); Checkbox Checkbox Checkbox Checkbox cbInternet=new Checkbox("Internet"); cbMuzik=new Checkbox("Muzik"); cbSinema=new Checkbox("Sinema"); cbTiyatro=new Checkbox("Tiyatro");

btnYaz=new Button("Yaz"); setLayout(new GridLayout(15,2)); add(lbAd); add(txtAd); add(lbSoyad); add(txtSoyad);

223

add(lbAdres); add(txtAdres); add(lbCinsiyet); add(new Checkbox("Erkek",cbCinsiyet,true)); add(new Checkbox("Kadin",cbCinsiyet,false)); add(lbHobi); add(cbInternet); add(cbMuzik); add(cbSinema); add(cbTiyatro); add(btnYaz); btnYaz.addActionListener(this); } public void actionPerformed(ActionEvent e) { if(e.getSource()==btnYaz) { System.out.println(txtAd.getText()+" "+txtSoyad.getText()); } } } Burada kullanlan teknii anlamann ok nemli olduunu dnyorum. ncelikle Appletin zerindeki nesnelerin olaylarn dinleyecek ekilde programlamalydm. Bunu gerekletirebilmek iin, snfa ActionListener arayzn uyguladm. Ardndan hangi bileen iin bir olay dinlemesinin gerekletirilmesini istiyorsam, o nesne ii addActionListener metodunu this parametresi ile kullandm. Bylece, bu rnekteki Button bileenine bu applet iinde yaplacak tklamalar ele alnabilecek ve kodlanabilecekti. Baka bir deyile, nesneye ait olas olaylarn dinlemeye alnmasn salamtm. Bu ilemin ardndan elbetteki, olay meydana geldiinde altrlacak kodlar yazacam bir metod gerekliydi. te buda, Button bileenlerine yaplan tklamalar dinleyen actionPerformed metodu. Bu metod ActionEvent isimli bir parametre alyor. Bu parametre sayesinde, hangi buton bileenine tklandn

224

dinleyebilirim. te bylece buton bileenine basldnda ileyecek olan satrlar burada yazm oldum. imdi bu sistemi deneme vakti geldi. Taraycda sayfam altrdm txtAd ve txtSoyad kontrollerine isim ve soyisim bilgilerimi girdim buton a tkladm ve ekrann sa alt kesindeki System Trayda yer alan JVM kahve semblnden, Open Console diyerek, console penceresine getim. Sonu olarak tklama olaym alglanm ve olaya karlk gelen kod satrlar altrlmt.

imdi aklma taklan baka bir nokta vard. Eer appletimde iki button bileeni olsayd. Her biri iin ayr ayr olay dinleyicilerimi yazacaktm? Nitekim, actionPerformed metodunun yaps buna msait deildi. Bu amala, applet e TextField ve TextArea kontrollerinin ieriini temizleyecek yeni bir Button bileeni ekledim. Kodun son hali aadaki gibi oldu. import java.awt.*; import java.applet.Applet; import java.awt.event.*;

225

public class Gui_1 extends Applet implements ActionListener { TextField txtAd; TextField txtSoyad; TextArea txtAdres; Button btnYaz; Button btnSil; public void init() { setBackground(Color.white); Label Label Label Label Label lbAd=new Label("Ad "); lbSoyad=new Label("Soyad "); lbAdres=new Label("Adres "); lbCinsiyet=new Label("Cinsiyet "); lbHobi=new Label("Hobi ");

txtAd=new TextField(); txtSoyad=new TextField(); txtAdres=new TextArea(2,5); CheckboxGroup cbCinsiyet=new CheckboxGroup(); Checkbox Checkbox Checkbox Checkbox cbInternet=new Checkbox("Internet"); cbMuzik=new Checkbox("Muzik"); cbSinema=new Checkbox("Sinema"); cbTiyatro=new Checkbox("Tiyatro");

btnYaz=new Button("Yaz"); btnSil=new Button("Sil"); setLayout(new GridLayout(16,2)); add(lbAd); add(txtAd); add(lbSoyad); add(txtSoyad);

226

add(lbAdres); add(txtAdres); add(lbCinsiyet); add(new Checkbox("Erkek",cbCinsiyet,true)); add(new Checkbox("Kadin",cbCinsiyet,false)); add(lbHobi); add(cbInternet); add(cbMuzik); add(cbSinema); add(cbTiyatro); add(btnYaz); add(btnSil); btnYaz.addActionListener(this); btnSil.addActionListener(this);

public void actionPerformed(ActionEvent e) { if(e.getSource()==btnYaz) { System.out.println(txtAd.getText()+" "+txtSoyad.getText()); } else if(e.getSource()==btnSil) { txtAd.setText(""); txtSoyad.setText(""); txtAdres.setText(""); repaint(); } } } lk hali;

227

Sil balkl Button bileenine tklandktan sonraki hali.

228

Her iki buton bileenide, ayn olay dinleyicisi ierisinde ele alnmt. actionPerformed dinleyicisinde, hangi butona tkland, ActionEvent parametresinin getSource metodu ile tespit edilmekteydi. Elbetteki awt paketinde yer alan dier grsel bileenler iin sadece bu olay dinleyicisi sz konusu deildi. in asl, nesneler zerindeki kullanc etkilerine gre dinleyiciler tanmlanmt. rnein, CheckBox bileenine tklanmas bu bileenin durumunun deimesi anlamna gelmekteydi ki bu durumda, ItemListener dinleyici metodu bu etkiyi ele alacakt. Dier nesneler iinde benzer durumlar sz konusu. Ama ne zaman? Bir dahaki kahve kokusunda.

Blm 16: Appletler ve JBuilder Geen hafta boyunca, Java dili ile Applet lerin nasl tasarlandn incelemeye altm. Mimari ksmnda yer alan hemen hereyi incelemitim. Bir AWT bileenin bir Applet e

229

nasl ekleneceini, bu bileenin bir takm temel zelliklerinin nasl ayarlanacan, bu bileene bal olay dinleyicilerinin ne ekilde uygulanmas gerektiini vs... Ancak karlatm en uratrc sorun, bileenlerin bir Applet zerinde yerleimlerinin Layout lar vastasyla ayarlanmaya almasyd. Akas, VS.NET gibi bir gelitirme ortamnn sunduu grsel tasarm rahatln zlemitim. Bu dnceler ierisinde Kadky n arka sokaklarnda yrrken ok sevgili bir dostum ile karlatm. Kendisinin sk bir Java programcs olduunu biliyordum. Beni ofisine davet etti. Ofiste bulunduum sre zarfnda konutuumuz ve tarttmz tek konu Applet lerin ve dier grsel java uygulamalarnn kolay bir ekilde tasarland ve daha ok uygulamann nasl alaca ve kodlamalar ile ilgilenilebildii, bir baka deyile asl nemli olan konulara zaman ayrlabildii, vs.net tarz bir gelitirme ortamnn var olup olmadyd. Deerli arkadam yznde kurnaz bir tebessm ile, "Sana gstermek istediim bir program var" dedi. Bilgisayarn bana getik ve ta taaa... JBuilder Enterprise 9! Adn ve methini ok duyduum bu yazlm gelitirme ortamn daha nce hi denememitim. Arkadam, "Ben java ile gelitirdiim uygulamalar burada yazyorum." dedi. Gzlerimde bir anda bir lt parladn hissettim. Tek sylediim "Yeni makalemi bugn burada yazabilir miyim?" olmutu. Her yazlmc, gelitirecei bir uygulama iin ncelikle, istekleri ve talepleri deerlendirerek ie balar. Sonra sistemin analizini ve tasarlanmasn gerekletirir. Gerekirse UML emalar yardmyla yazlmn tasar plannda oluturur. Sonraki adm ise, kodlamalarn yaplmasdr. Ancak ou zaman ne ben ne de dier pek ok yazlmc Notepad gibi muhteem bir editor ile bu tarz projeleri gelitirmek istemez. nk bu tarz bir yntem izlendiinde, yazlmn nem arz eden konularna ayrlacak olan zaman, notepad ile yazlan kodlarda, bileenlerin ekran zerine dzgn bir ekilde yerletirilmesinin salanmas, olay dinleyicilerinin ayarlanmas gibi gereksiz yere zaman alc konulara harcanr. Eer bu byle olmasayd oumuz bu gn C# ile gelitireceimiz projeleri Vs.Net gibi bir ortamda yazmazdk. te JBuilder da Java ile yazlm gelitirmek zere tasarlanm bir yazlm gelitirme aracyd. ok kr ki, arkadamda bu yazlmn olmas benim bu ortam test etmem
230

ve bir Applet i rnek olarak gelitirmem iin bulunmaz frsatt. Bir an bile dnmeden bu frsat deerlendirmem gerektiine karar verdim. O gn ilk yaptm, Help dosyalarndan Tutorial lara bakmak olmutu. Hedefim, bir Applet i gnl rahatlyla ve kolayca gelitirebilmek ve grsel yazlm gelitirme ortamlarnn tm nimetlerinden faydalanabilmekti. Bu amala, bir Applet in nasl tasarlandnn ve programlandnn anlatld Tutorial bir solukta okuyuverdim. Ardndan hemen uygulamaya getim. lk olarak bana bir proje lazmd. Vs.Net teki Solution kavramnn karl JBuilder iin Project di. File-> New Project sekmesini setiimde, yeni bir proje oluturmam iin gerekli admlar salayan bir sihirbaz ile karlatm.

Bu ilk admda tek yaptm, Proje iin bir isim belirlemek oldu. Hemen ikinci adma getim. kinci admda en nemli ksmlardan birisi, JDK isimli yerdi. Burada gelitireceim uygulamay Java nn hangi gelitirme kiti ile yazacam belirtebilmekteydim. Output Path ile java dosyalarnn derlenmesi sonucu oluturulacak snf dosyalarnn hangi yolda
231

olaca, Backup Path ile yedeklemelerin nereye yaplaca belirleniyordu. Working Directory yi henz tam olarak kestirememitim. Bunun yerine projeyi tamamladmda bu klasr inceleyip ne olup bittiine bakmaya karar verdim.

Bu admda getikten sonra sra proje oluturmann son admna gelmiti. Bu admda, proje hakknda bir takm bilgileri girdim. rnein projenin adn, ksa bir aklamasn, versiyon numarasn vs... Tutorial dan rendiim kadar ile, bu admda belirtilenler html bazl bir dosyada toplanp, proje hakknda bir takm temel bilgileri salamaktayd.

232

Son olarak Finish diyerek projenin oluturulmasn saladm. Proje oluturulduunda, son admda girdiim verileri ieren bir html dkmannnda otomatik olarak yazldn grdm.

233

Artk projem hazr olduunda gre, bu projeye bir Applet ekleyebilirdim. Tek yapmam gereken File->New mensnden alacak olan Object Gallery de Web sekmesine gelmek ve Applet ablonunu semekti.

Bu ilemin ardndan Applet ile ilgili bir takm ayarlamalarn yapld baka bir sihirbaz ile karlatm.

234

lk admda herey gayet ak ve netti. Appletin yer alaca paketin ad standart olarak, proje ismiydi. Applet iin bir snf ad belirtilmiti. Bu snf adn u an iin deitirmedim. Base class ile, bir appletin tretilmesi gereken Applet snfn tanmlamtm. zellikle dikkatimi eken nokta Generate standart methods seeneidi. Varsaylan olarak iaretli olmayan bu seenei iaretledim. nk bu seenek ile, Applet iin gerekli standart bir takm metodlarn (init gibi) otomatik olarak oluturulacan dnyordum. Sihirbazda bir sonraki adm Applet in dardan parametre alp alamayaca ile ilgiliydi. u an iin Applet in html sayfasndan parametre almayacan dndm iin bu adm geerek nc adma geldim. nc admda, Appletin test edilmesi iin oluturulacak html dkmanna ait bilgiler yer alyordu.

235

Burada, HTML dkmann balk bilgisini, dosya adn, Applet in boyutlarn belirledim. Codebase zellii ile, Applet in almas iin gerekli snf dosyalarnn bulunduu klasrler belirleniyordu. Sonraki admda deitirmeden getiimde, JBuilder benim iin, Applet dosyasn otomatik olarak oluturmu ve gerekli kodlar yerletirmiti. u haliyle Applet in kodlar aadaki gibiydi. package appletuygulamalari; import java.awt.*; import java.awt.event.*; import java.applet.*; public class Applet1 extends Applet { private boolean isStandalone = false; public String getParameter(String key, String def) { return isStandalone ? System.getProperty(key, def):(getParameter(key) != null ? getParameter(key) : def);

236

} public Applet1() { } public void init() { try { jbInit(); } catch(Exception e) { e.printStackTrace(); } } private void jbInit() throws Exception { } public void start() { } public void stop() { } public void destroy() { } public String getAppletInfo() { return "Applet Information"; }

237

public String[][] getParameterInfo() { return null; } } Oluturulan bu Applet dosyas ile, geen haftalarda oluturduum Applet ler arasnda ok fazla fark yoktu. Hereyden nce, dosyaya baktmda en azndan bir Applet olduunu, bu nedenle Applet snfndan tretildiini biliyordum. Bununla birlikte, olay dinleyicilerinin kullanlabilmesi iin ve AWT bileenlerinin oluturulabilmesi iin gerekli applet, awt ve event paketlerinin referans edildiinide anlamtm. Bir Applet in yaam sresi iinde devreye giren init, start, stop , destroy gibi metodlarnda ne ie yaradn biliyordum. Ekstradan JBuilder tarafndan eklenmi ilave kodlar vard. Ancak u an iin bu kodlar pek umurumda deildi. Bir an nce awt bileenlerini eklemek istiyordum. Bu amala hemen design sekmesine getim ve ite... Oluturduum applet ekran st taraftaki koca bir bileen paleti ile karmda duruyordu. Sa tarafta ne olduklarn adm gibi bildiim zellikler pencereside yzme ayr bir glmseme katmt.

238

lk olarak, appletim ile ilgili bir takm zellikleri deitirdim. Sonu olarak bu deiikliklerin koda nasl yanstlacan merak ediyordum. Applet in arka plan rengini deitirdim. Tam bu srada dikkatimi layout isimli zellik ekti. Bu zelliin ald bir takm deerler vard.

239

Layout larn, AWT bileenlerinin Applet zerine nasl konumlandrlacan belirlemekte kullanldn biliyordum. Hatta geen haftaki denemelerimde en ok zorlandm yerleim sorununu bir Layout nesnesi yardmyla zmtm. Yinede istediim gibi olmamt. JBuilder, bana bir sr layout eidi sunmaktayd. Biraz deneme yanlmadan sonra en uygun olanann XYLayout olduunu tespit ettim. nk XYLayout sayesinde, AWT bileenlerini Applet zerinde serbest olarak istediim yere konumlandrabilecektim. Yaptm bu ayarlamalardan sonra kodlarma baktmda aadaki deiikliklerin olduunu farkettim. Hereyden nce, XYLayout xYLayout1 = new XYLayout(); kod satrlar ile XYLayout nesnesi oluturulmutu. Ancak bu Layout nesnesi, java gelitirme kiti ile gelen snflardan deildi. Onun yerine, com.borland.jbcl.layout paketinde yer alan Layout snflarndan birisiydi. Zaten bu nedenle, bu paket Applet in banda uygulamaya import edilmiti. Dier yandan jbInit metodu iinde, bu XYLayout un Applet e uygulanmas iin aadaki kod satrnn eklenmi olduunu grdm. this.setLayout(xYLayout1); Artk Applet im iim setiim Layout desenide ayarlandna gre gnl rahatlyla, AWT bileenlerini oluturabilirdim. Tek yapmam gereken bileen paletinden AWT sekmesine gelmek bir bileen izmek ve bu bileeni mouse ile Applet in alma alan zerine izmekti.

Bbir ka basit bileeni Applet zerine yerletirdikten ve bunlarn belli bal zelliklerini Properties penceresinden deitirdikten sonra ise bu zelliklerin Applet dosyasna nasl yanstldn incelemeye baladm.

240

Applet zerinde iki Label bileeni bir TextField bileeni ve bir de Button bileeni vard. Bu bileenlerin baz zelliklerini deitirdiimde kodun ierisinde JBuilder n aadaki eklemeleri yaptn farkettim. lk olarak Applet kodlarnn banda, her bir AWT bileeni iin birer nesne rnei oluturulduunu grdm. TextField tfSayi = new TextField(); Label label1 = new Label(); Button btnKare = new Button(); Label label2 = new Label(); Bu nesnelerin ayarladm zellikleri ise, jbInit isimli metod ierisine yazlmt. Herhangibir bileenin zelliklerini ayarlamak iin Properties penceresini kullanmtm. Tek satr kod yazmadan, JBuilder, bu ilemlerimi jbInit isimli metodu ierisine otomatik olarak yazvermiti. private void jbInit() throws Exception { tfSayi.setFont(new java.awt.Font("Dialog", 0, 14)); this.setBackground(new Color(255, 173, 69)); this.setLayout(xYLayout1); label1.setFont(new java.awt.Font("Dialog", 1, 14)); label1.setText("Sayi"); btnKare.setFont(new java.awt.Font("Dialog", 0, 14)); btnKare.setLabel("Karesi"); label2.setFont(new java.awt.Font("Dialog", 1, 24)); label2.setForeground(Color.red); label2.setText("label2");

241

this.add(tfSayi, new XYConstraints(128, 36, 160, 24)); this.add(btnKare, new XYConstraints(295, 34, 90, 30)); this.add(label1, new XYConstraints(69, 36, 46, 26)); this.add(label2, new XYConstraints(125, 74, 262, 37)); } TextField bileeninin Font ayarlamalar setFont metodu ile yaplmt. Ayn metod dier bileenlerde de kullanlmt. Applet in arka plan rengi setBackground metodu kullanlarak belirlenmekteydi. Bu metoda parametre olarak Color snfndan bir nesne aktarlm ve bu nesde R,G,B (Red,Green,Blue) renk tonlarn esas alarak arka plan renklendirmiti. Bileenlerin balklarnda yazacak metinler setText veya setLabel metodlar ile belirlenmekteydi. Bu metod ierisinde belkide en nemli ksm, bileenlerin Applet e add metodu ile ekleni ekilleriyle ilgiliydi. Bu metod iki parametre almt. lk parametre ile, hangi bileenin eklenecei belirleniyordu. kinci parametre ise XYConstraints snfndan bir nesne almaktayd. Bu nesnenin 4 parametresinden ilk ikisi bileenin boyutlarn son ikisi ise X ve Y koordinatlarn belirtmekteydi. XYConstraints snfda, XYLayout snf gibi, com.borland.jbcl.layout paketinde yer alan bir snft. Elbette add metodunun bu eklinin uygulanmas, bir XYLayout nesnesinin bu Applet iin uygulanmasnda gerektirmekteydi. jbInit metodu, bileenlerin zelliklerinin belirlenmesi ve Applet e eklenmesinde grev alyordu. Normalde Notepad ile yazlan bir Applet te bu kod satrlarn init metodu ierisine dorudan yerletirecektim. Nitekim JBuilder bu ii daha gvenli bir hale getirmek ve bileenlerin Applet e eklenmesi srasnda oluabilecek istisnalar kontrol altna alabilmek iin init metodunu aadaki gibi dzenlemiti. public void init() { try {

242

} catch(Exception e) { e.printStackTrace(); }

jbInit();

Srada ise Button bileenine basldnda gerekletirilecek olaylarn kodlanmas vard. Bu amala ilk yaptm, Button bileenine ift tklamak oldu. Olay metodlarnn bu ekilde eklendiklerinde, o bileen iin varsaylan olay metodunun oluturulacan biliyordum. Olay metodu eklemesi iin elbetteki Events sekmesinide kullanabilirdim. rnein, Button bileeni ile kullanabileceim olay metodlar aadaki ekilde grlenlerdi.

Sonu olarak, JBuilder aadaki gibi bir olay metodu oluturdu.


243

void btnKare_actionPerformed(ActionEvent e) { } Normal artlarda, bir Button bileeni iin olay metodu oluturmak isteseydim, aadaki gibi bir metod yazmam gerekicekti. Bu metod iinde, Applet iinde actionPerformed olayna cevap verebilecek bir ka bileen olacan dnerekten, hangi bileen iin bu olay metodunun altrlacana ve ne ekilde alacana karar vermek amacyla, ActionEvent parametresinin getSource metodunnu kullanmam gerekiyordu. Oysaki JBuilder bunu yapmamt. Onun yerine sanki sadece bu Button bileeni iin alacak bir olay metodu yazmt. public void actionPerformed(ActionEvent e) { if(e.getSource()==btnYaz) { } } Peki JBuilder bu durumu nasl gerekletirmiti? Kodlar incelemeye devam ettim. actionPerformed olay metodu iin, ActionListener arayznn Applet snfna uygulanm olmas gerekiyordu. Oysaki Applet e ait snf tanmlamasnda byle bir arayz uygulanmamt. public class Applet1 extends Applet { Tam bu srada Applete ikinci bir snfn daha eklendiini grdm. class Applet1_btnKare_actionAdapter implements java.awt.event.ActionListener { Applet1 adaptee;

244

Applet1_btnKare_actionAdapter(Applet1 adaptee) { this.adaptee = adaptee; } public void actionPerformed(ActionEvent e) { adaptee.btnKare_actionPerformed(e); } } Asl bu snf ActionListener arayzn uygulamt. Snfn ad, Applet ve Bileen adlarndan oluturulmutu. Snf iinde ilk satrda, Applet1 snfndan (ki bu appletimin ad oluyordu) bir nesne tanmlanmt. Snfn yapc metodunda da bu Applet1 nesnesi kullanlmt. Peki ama bunlar ne anlama geliyordu. Sorunun cevab izleyen actionPerformed metodunda yatmaktayd. Button bileenine basldnda, Applet in olay dinleyicisi bu yeni snf ierisinde yer alan actionPerformed metodunu devreye sokuyordu. Bu metod ise, ActionEvent parametresini, button bileeni iin oluturulan btnKare_actionPerformed metoduna gndermekteydi. Bu tasarm deseni sayesinde, her bileen iin yazlacak olay metodlar ayr ayr olacak ekilde oluturulmaktayd. Bylece bileen olaylarnn tek bir metod iinden ayrtrlarak ele alnmasnn nne geilmi oluyordu. Ancak yinede eksik bir eyler vard. Sonu olarak bir ekilde, olay dinleyicisinin bir yerlerde bu Button bileeni iin eklenmi olmas gerekirdi. Kodu bir kere daha inceledikten sonra, JbInit metodunda aadaki satr farkettim. btnKare.addActionListener(new Applet1_btnKare_actionAdapter(this)); Normalde, bu Button bileeni iin olay dinleyicisi eklenirken addActionListener metodu sadece this parametresini alrd. Burada ise, olay dinleyicisi olarak, Applet1_btnKare_actionAdapter snf trnden bir nesne oluturulmu ve bu nesneye this parametresi yani Applet

245

snfnn kendisi gnderilmiti. Bir baka deyile olay dinleme grevini bu yeni snf stlenmekteydi. Artk Button bileenine basldnda neler olacan kodlayabilirdim. Burada ok daha gzel bir ey farkettim. Borland uzun sredir, gelitirme ortamlarnda intellisense zelliini kullanyordu. Bu zelliin JBuilder iindede olmas gerekten ok iyiydi. Nitekim . iaretinden sonra ilgili nesne ile kullanabileceim metodlar aadaki gibi karma geliyordu. Tek grdm eksik, bir metod ad stne geldiimde, Vs.Net te olduu gibi metod hakknda ksa bir aklamann ekrana gelmiyor olmasyd.

Buna ramen kodlar yazmak kolayd. Bu mutluluk ve huzur iinde aadaki kodlar oluturdum. Kodlarda gerekleen olay son derece basitti. Gvenli bir try-catch blou iinde, nce TextField a girilen deeri getText metodu ile almtm. Ardndan, bu deeri double tipinden bir deikene aktarmak iin Double snfnn parseDouble metodunu kullandm. Sonra Math snfnn pow metodu ile bu deerin karesini buldum ve sonucu String snfnn valueOf metodu ile String trnden bir deikene aktardm. Son olarak bu deeri label bileeninde setText metodu ile gsterdim. void btnKare_actionPerformed(ActionEvent e) { try { String sayi = tfSayi.getText(); double deger=Double.parseDouble(sayi);
246

deger=java.lang.Math.pow(deger,2); String sonuc=String.valueOf(deger); label2.setText(sonuc); } catch(Exception hata) { label2.setText(hata.toString()); } } Tm bu ilemlerden sonra tek yapmam gereken, projeyi derlemek ve altrmakt.

Sonu ise aadaki gibi oldu. Applet baarl bir ekilde alt. Bu mutluluu yaarken gnein oktan battn ve ofisin kapanmak zere olduunu farkettim. Masamda 3 kulplu bardak ii bo ve ho bir kahve kokusu ile duruyordu. Java dili ile bireyler gelitirmenin bu kadar elenceli ve gzel olacan tahmin etmemitim. Ancak elbetteki dilin temellerini bilmeden yaptklarmdanda bir ey anlayamaz ve beceremezdim. Artk rahat ve huzurlu bir ekilde evime dnebilirdim.

247

Blm 17: Layout Getiimiz hafta hayatmn en mutlu gnlerinden birisini, deerli bir arkadamnn ofisinde, bilgisayarnn banda JBuilder kullanarak geirdim. Bu hafta, o gn mumla aradm sylemek isterim. JBuilder ile daha nce hi uygulama gelitirmemi olmama ramen, kolayca adapte olmutum. Elbetteki benim iin en byk rahatl, Applet gibi grsel uygulamalarn ekran tasarmlarnn son derece kolay bir ekilde yaplabilmesiydi. Bu hafta yine sevimsiz notepad editorm ile babaaym. Aslnda amacm arkadamn bilgisayarnda JBuilder ile baka almalarda yapmakt. Fakat kendisi tatile kt iin banada notepad ile bir kahve molas geirmek kald. zellikle notepad editorn kullanarak applet tasarlamann en zor yanlarndan birisi, applet zerindeki bileenlerin yerleim ekillerinin ayarlanmasnn zorluudur. Bu hafta ne yapp edip, bu fobiyi yenmeye karar verdim ve java dilinde Layout

248

kavramn incelemeye baladm. Layout lar applet zerine yerletirilecek bileenlerin belli bir nizamda olmasn salamaktadrlar. Java paketiyle gelen Layout snflar 5 adettir. Java Layouts GridLayout BorderLayout FlowLayout CardLayout GridBagLayout ncelikle ie en kolay olanndan baladm. FlowLayout. Layout snflarn anlamann en iyi yolu elbette onlar bir rnek zerinde uygulamakla mmkn olabilirdi. Bu amala ok basit olarak aadaki gibi bir java rnei gelitirdim. import java.awt.*; import java.applet.Applet; public class Layouts extends Applet { TextField tf1; TextField tf2; Button bt1; Label lb1; Label lb2; public void init() { setLayout(new FlowLayout(FlowLayout.CENTER,15,30)); lb1=new Label("Username"); tf1=new TextField(25); lb2=new Label("Password"); tf2=new TextField(25); bt1=new Button(" OK ");

249

add(lb1); add(tf1); add(lb2); add(tf2); add(bt1); } }

Burada tek yaptm, applet zerine yerleecek bileenlerin FlowLayout a gre dzenlenmesiydi. Applet in FlowLayout u uygulayacan belirtmek iin, setLayout(new FlowLayout(FlowLayout.CENTER,15,30)); kod satrn kullandm. Burada, bileenlerin Applet zerinde bulunduklar satrda ortalanarak yerletirilecekleri ve yatay olarak aralarnda 15 piksel, dikey olarak ise 30 piksel bouk olaca belirtiliyor. Peki ama bu yerleim nasl oluyor? Nitekim kaynaklarda, FlowLayout un bileenleri sola ve aa doru hizalad syleniyordu. Denemekten baka arem olmadn dnerek hemen ie koyuldum ve basit bir html sayfasnda applet tagm aadaki gibi ekledim. <APPLET CODE="Layouts.class" width="300" height="500"> </APPLET> imdi bu html sayfasn altrdmda aadaki gibi bir grnt elde ettim.

250

Doruyu sylemek gerekirse kel alaka bir tasarm olmutu. FlowLayout iin dier iki durum, yerleim eklinin sola dayal olmasn belirten FlowLayout.LEFT ve saa dayal olmasn belirten FlowLayout.RIGHT seenekleriydi. nce LEFT durumunu inceledim ve aadaki ekran grntsn elde ettim.

Sanki durumu anlamaya balam gibiydim. Bu kez RIGHT durumunu denedim ve aadaki sonucu elde

ettim. Grnen o ki, dzgn bir tasarm yapmak istiyorsam bunu ncelikle kafamda yapmal ve Applet in boyutlarn ok tutarl belirtmeliydim. Ancak bu ekilde dzgn bir tasarm elde edebilirdim. u an iin deneme yanlma yntemini kullanmaktan baka bir ey aklma gelmiyor akas. rnein, en uzun Label olan Username ile TextField larn boyu dnldnde Applet tagn aadaki gibi dzenlemek daha mantkl geliyordu. <APPLET CODE="Layouts.class" width="250" height="500"> </APPLET> Java kodunda da, FlowLayout dizilimini FlowLayout.LEFT olarak belirlediimde, daha dzenli bir ekran grnts elde ettim. Geri bu varsaymsal yaklam ile kullanlan teknik pek houma gitmemiti ama en azndan buz dann st ksmn biraz olsun yontmay baarabilmitim.
251

Bu rnekten sonra, arkadam bir kat daha zledim desem yalan olmaz. Heleki JBuilder uygulamasn. Oradaki tasarm rahatl gerektende muhteemdi. Bu srada aklma baka bir ey geldi. Acaba, bir Layout dzeneini, bir Panel bileenine uygulayabilir miydim? Eer byle bir ey sz konusu olursa, grsel tasarm biraz daha kolaylatrabilirdim. Bu amala aadaki gibi bir rnek gelitirdim. import java.awt.*; import java.applet.Applet; public class Layouts extends Applet { TextField tf1; TextField tf2; Button bt1; Label lb1; Label lb2; Panel p1; public void init() { p1=new Panel(); p1.setBackground(Color.yellow); p1.setLayout(new FlowLayout(FlowLayout.LEFT)); lb1=new Label("Username"); tf1=new TextField(25); lb2=new Label("Password");
252

tf2=new TextField(25); bt1=new Button(" OK "); p1.add(lb1); p1.add(tf1); p1.add(lb2); p1.add(tf2); p1.add(bt1); add(p1); } }

lk olarak, bir Panel bileeni oluturdum ve bu bileen zerine yerletireceim dier bileenlerin FlowLayout dzeneine gre konumlandrlmalarn salamak iin Panel bileenine, p1.setLayout(new FlowLayout(FlowLayout.LEFT)); satrndaki setLayout metodunu uyguladm. Bylece, Panel bileeni zerine yerleecek bileenler, FlowLayot dzeneine gre, Layout un solundan hizalanacak ekilde konumlanacaklard. Bileenleri Panel e eklemek iin, Panel snfna ait add metodunu kullandm. Tabi bu ilemlerden sonra Panel bileeninide, Applet e add metodu ile eklemeyi unutmadm. Bu admlardan sonra, Java dosyasn derleyip applet i ieren html sayfasn ilk altrdmda aadaki sonucu elde ettim.

Byle olaca belliydi zaten. Applet tagnda width zelliini arttrmam gerekiyordu. Bu deeri 600 olarak belirledim. imdi elde ettiim sonu ok daha iyiydi.

253

Layout snflar bitmek bilmiyordu. Srada BorderLayout snf vard. Bu snfn en ilgin yan, Applet ekrannn, NBA basketbol takmlarnn liglerinde gruplanlarna benzer bir yapda ayrtrlyor olmasyd. Dou Grubu, Merkez Grubu, Bat Grubu, Kuzey Grubu ve Gney Grubu. Yani, applet zerine ekleyeceim bileenleri, bu gruplara yerletirmem gerekiyordu. Bunu grsel olarak anlayabilmek iin, kaynaklarm aratrdm ve yukardaki rnee bu kez BorderLayout dzeneini uyguladm. import java.awt.*; import java.applet.Applet; public class Layouts extends Applet { TextField tf1; TextField tf2; Button bt1; Label lb1; Label lb2; public void init() { setLayout(new BorderLayout()); lb1=new Label("Username"); tf1=new TextField(25); lb2=new Label("Password"); tf2=new TextField(25); bt1=new Button(" OK "); add("North",lb1); add("Center",tf1); add("West",lb2); add("South",tf2); add("East",bt1); } } Applet zerindeki bileenlerin BorderLayout dzeneine gre yerletirileceini,

254

setLayout(new BorderLayout()); satr belirtiyordu. BorderLayout, Applet i 5 yn blgesine bld iin, her bileeni Applet e eklerken add metoduna ilk parametre olarak, bileenin hangi blgeye yerletirileceinin belirtilmesi gerekiyordu. Bu ilemde aadaki satrla gerekletirmekteydi. add("North",lb1); add("Center",tf1); add("West",lb2); add("South",tf2); add("East",bt1); rnein, tf2 isimli TextField bileeni Appletin South (Gney) blgesine yerleecekti. Artk Applet i kullandm html sayfasn altrp sonular grmek istiyordum. Ama sonular gstermeye ekiniyorum akas. BorderLayout un Applet ekranna uygulanmas sonucu aadaki gibi muhteem tesi bir tasarm elde ettim. Tarihi bir baar olduunu belirtmek isterim.

255

in kt yan, belli bir blgeye sadece tek bir bileen yerletirebiliyor olmasyd. BorderLayout dzeneinin nerede kullanlacan dnrken, dier Layout lar incelemenin daha uygun olacan farkettim. Nitekim, BorderLayout her ne kadar yukardaki ekran tasarm iin uygun olmasada elbetteki kullanld bir takm yerler olabilirdi. Layout lar ile uramak gerekten insana skc geliyor. Artk JBuilder gibi grsel tasarm aralarnn o kadar paraya gerekten deydiini syleyebilirim. Hemde gnl rahatlyla. Bu dnceler eliinde kendime yeni bir fincan kahve aldktan sonra bir dier Layout snf olan GridLayout u incelemeye baladm. GridLayout ile nispeten biraz daha gzel ve kolay form tasarmlar oluturabileceimi dnyordum. Yapmam gereken son derece basitti. Ayn rnei GridLayout snf ile gelitirmek. import java.awt.*;

256

import java.applet.Applet; public class Layouts extends Applet { TextField tf1; TextField tf2; Button bt1; Label lb1; Label lb2; Panel p1; Panel p2; public void init() { setLayout(new GridLayout(2,1)); p1=new Panel(); p1.setBackground(Color.orange); p1.setLayout(new FlowLayout(FlowLayout.LEFT)); p2=new Panel(); p2.setBackground(Color.blue); lb1=new Label("Username"); tf1=new TextField(25); lb2=new Label("Password"); tf2=new TextField(25); bt1=new Button(" OK "); p1.add(lb1); p1.add(tf1); p1.add(lb2); p1.add(tf2); p1.add(bt1); add(p1); add(p2); } }

257

Bu kez, Applete iki Panel bileeni ekledim. Bu iki Panel bileeninde 2 satr ve 1 stunluk bir GridLayout dzenei iinde Applet e ekledim. GridLayout nesneleri, temel olarak iki parametre almakta. lk parametre, satr saysn belirtirken, ikinci parametrede doal olarak stun saysn belirtiyor. Bununla birlikte, GridLayout snfnn 4 parametre alan bir dier yapcsda mevcut. Bu yapcnn ald son iki parametre ise, Grid hcrelerine yerletirilecek bileenlerin arasndaki yatay ve dikey uzaklklar piksel olarak belirtmekte. Bu rnei gelitirdikten sonra Applet tagn aadaki gibi dzenledim. <APPLET CODE="Layouts.class" width="610" height="100"> </APPLET> Sonu ise, FB (FB lilerin ampiyonluklarnda tebrik ederim bu arada) renkleriyle aadaki gibi olutu. BJK taraftar olmama ramen, tasarm byle renklendirebildiim iin ok mutlu oldum. Demek ki, Layout lar bir arada kullanarak ve iin iine Panel bileenlerini katarak daha salam tasarmlar oluturulabilirdi. Notepad ile dahi olsa. Ama bununla kim urardki gzelim JBuilder varken. (Elbette ben urardm sanrm.)

GridLayout snfnda getim derken karma daha karmak bir Layout snf kverdi. GridBagLayout. Bunu anlayabilmek iin, Bilim Teknik dergisinde her ay kan sorular zer gibi kat kaleme sarlp almam gerektiini itiraf etmeliyim. GridBagLayout snf ile, Applet zerinde ok karmak ekran tasarmlarn yapabilmek mmkn. Ancak bu ii baarabilmek iin bir o kadarda kark bir teknik kullanmak gerekiyor. Burada nemli olan nokta, Applet zerine yerleecek bileenlerin X,Y koordinatlar ile uzunluk ve ykseklik bilgileri. Nitekim, GridBagLayout tekniinde, Applet karelere blnyor ve bileenler bu kareler zerine yerletiriliyor. imdi burada hakketten ele kat kalem almak ve izmek lazm. Ancak dijital
258

bir ortamda olduumuzu dnrsek bu i iin, gelimi grafik programlarnda kullanabilirim. te bu amala bu Layout snfn kullanarak, Applet zerinde konumlandrlacak bir Button nesnesini gz nne alarak basit bir izim oluturdum.

Temel olarak yapacam ilem buydu. Applet ekrann karelere blmek. rnein bir Button yerletirmek istiyorum. nceden bu Button bileenin X, Y koordinatlarn, uzunluk ve ykseklik bilgilerini, yukardaki gibi bir ekli baz alarak bilmem gerekiyor. Olayn esprisi buydu ite. Bu nedenle de GridBagLayout dier Layout snflarna gre daha karmak Applet tasarmlar oluturmamza izin veriyordu. nk bir ekran pozisyonlamas iin gereki 4 nemli unsuru baz alyordu. X,Y Koordinatlar, uzunluk ve ykseklik. Peki bu zahmetli tasarm kodlamada nasl gerekletirebilirdim. Bu amala epeyce bir saatimi, srf GridBagLayout un nasl kullanldn anlamaya harcadm. Sonu olarak aadaki gibi bir rnek gelitirdim. import java.awt.*; import java.applet.Applet; public class Layouts extends Applet { TextField tf1; TextField tf2;
259

Button bt1; Label lb1; Label lb2; GridBagLayout gbl; GridBagConstraints gbc; public void init() { gbl=new GridBagLayout(); gbc=new GridBagConstraints(); setLayout(gbl); gbc.insets=new Insets(2,2,2,2); gbc.fill=GridBagConstraints.BOTH; gbc.gridx=0; gbc.gridy=0; gbc.gridwidth=5; gbc.gridheight=1; lb1=new Label("Username"); gbl.setConstraints(lb1,gbc); add(lb1); gbc.gridx=6; gbc.gridy=0; gbc.gridwidth=5; gbc.gridheight=1; tf1=new TextField(25); gbl.setConstraints(tf1,gbc); add(tf1); gbc.gridx=0; gbc.gridy=1; gbc.gridwidth=5; gbc.gridheight=1; lb2=new Label("Password"); gbl.setConstraints(lb2,gbc); add(lb2);

260

gbc.gridx=6; gbc.gridy=1; gbc.gridwidth=5; gbc.gridheight=1; tf2=new TextField(25); gbl.setConstraints(tf2,gbc); add(tf2); gbc.gridx=0; gbc.gridy=3; gbc.gridwidth=5; gbc.gridheight=1; bt1=new Button(" OK "); gbl.setConstraints(bt1,gbc); add(bt1);

} }

Kodlar yazdktan sonra nce Applet in nasl altna baktm. Sonu hite fena deildi.

Nasl olmutuda bylesine gzel bir sonu elde edebilmitim. Hereyden nce, GridBagLayout snfn oluturdum. Ancak burada GridBagConstraints isimli baka bir snf daha vard. Bu snf, her bir bileen iin gerekli X, Y koordinatlar ile, uzunluk ve ykseklik ayarlamalarn tayacak nesneler rneklendirmek amacyla kullanlmaktayd. Dolaysyla bir bileeni, GridBagLayout snf nesnesine eklerken setConstraints metodu ikinci parametre olarak, GridBagConstraints snfna ait nesne rneini almaktayd. Bylece, setConstraints metodunun ilk parametresinde belirtilen bileen, Applet zerinde belirtilen X, Y koordinatlarna, belirtilen ykseklik ve uzunlukta iziliyordu. Burada uzunluk ve ykseklik piksel baznda deil hce bazndadr. rnein aadaki satrlar gz nne alalm.

261

gbc.gridx=6; gbc.gridy=1; gbc.gridwidth=5; gbc.gridheight=1; tf2=new TextField(25); gbl.setConstraints(tf2,gbc); add(tf2); Burada TextField bileeni, X=6, Y=1 koordinatlarna yerletirilmitir. Uzunluu 5 hcre kadar, ykseklii ise 1 hcre kadardr. Daha sonra, bu bileen GridBagLayout nesnesine, setConstraints metodu ile eklenmitir. Artk, bu bileeni Applet e add metodu ile eklediimizde, GridBagLayout konumlar esas alnacaktr. gbc.insets=new Insets(2,2,2,2); gbc.fill=GridBagConstraints.BOTH; Satrlarna gelince. Bu satrlarda, GridBagConstraint nesnesinin bir takm zellikleri belirlenmektedir. Bunlardan birisi insets zelliidir. Insets ile, hcreler iindeki bileenlerin hcrenin kenarlarna olan uzakl belirtilmektedir. Bir baka deyile boluk miktar. Fill zellii ileyse, GridBagLayout un genilemesi durumunda, hcre ii bileenlerin her ynde eit ekilde genilemesi belirtilmitir. Bu zor ama gl Layout tan sonra, incelemeyi unuttuum bir Layout daha olduunu farkettim. CardLayout. lk bata iskambil desteleri ile bir alakas olabilir mi diye dndm. Gerektende yleymi. CardLayout ta, birbirlerinin stne binen katmanlar sz konusu. in gzel yan ise, CardLayout lar ile, birbirinden farkl katmanlarn tasarlanabilmesi ve alma zamannda bu katmanlardan sadece birisinin grnr olmas. Dolaysyla bu katmanlar arasnda gezinmek iin, olay gdml programlama tekniklerini kullanmak gerekiyor. Nasl m? te rnek. import java.awt.*; import java.applet.Applet; import java.awt.event.*;

262

public class Layouts extends Applet implements ActionListener { TextField tf1; TextField tf2; Button bt1; Button bt2; Label lb1; Label lb2; Label lb3; Panel p1; Panel p2; Panel p3; Panel p4; CardLayout iskambil; public void init() { iskambil=new CardLayout(); p1=new Panel(); p2=new Panel(); p2.setBackground(Color.blue); p3=new Panel(); p3.setBackground(Color.green); p4=new Panel(); iskambil=new CardLayout(); p4.setLayout(iskambil); lb1=new Label("Username"); p1.add(lb1); tf1=new TextField(25); p1.add(tf1); lb2=new Label("Password"); p1.add(lb2); tf2=new TextField(25); p1.add(tf2);

263

bt1=new Button("Onceki"); bt1.addActionListener(this); bt2=new Button("Sonraki"); bt2.addActionListener(this); p2.add(bt1); p2.add(bt2); p4.add("Giris",p1); p4.add("Diger",p3); add(p4); add(p2); } public void actionPerformed(ActionEvent e) { if(e.getActionCommand()=="Onceki") { iskambil.previous(p4); } else if(e.getActionCommand()=="Sonraki") { iskambil.next(p4); } } } Ve sonu. CardLayout daha gzel bir tasarm sundu. Tek bir applet sayfasnda st ste duran paneller arasnda gezebilme imkan.

264

Artk Layout lara veda etme vakti geldi. Gelecek kahve molalarnda umarm JBuilder ile daha fazla ilgilenme frsat bulabilirim. Katetmem gereken daha ok kilometre ta var. Network programlama, veritabanlar, web servisleri, swing bileenleri, windows uygulamalar vs...

Blm 18: Pencereler Bir ka haftadr Java dilini popler yapan Applet ler ile urayorum. Buna karn gnmz dnyasnn bir programlama dilinden bekledikleri arasnda mutlaka windows uygulamalarnn var olmas gerektiini dnyorum. Sonu olarak Applet ler her ne kadar ok baarl olsalarda, zaman zaman windows uygulamalar gelitirmemizde gerekiyor. Bir windows uygulamasnn belkide en temel zellii mutlaka bir Form (Nam- dier pencere diyebiliriz) ekranna sahip olmas. Peki java dilinde, windows uygulamlar oluturmak iin nasl bir yol izlemem gerekir. te bu hafta boyunca, java dili ile bamsz olarak alabilen pencereleri incelemeye altm. Sun n Java paltformu, Microsoft un ciddi rakiplerinden birisi. Belkide tek ciddi rakibi. Ancak bu rekabet zaman zaman biraz komik olaylarada neden olmuyor deil. rnein, yaptm aratrmalarda grdm ki, Windows uygulamarnda Form kavram, java dilinde Frame olarak adlandrlyor. Bu ksa politik dncelerden sonra, artk ilk form ekranm, pardon dzeltiyorum; ilk frame ekranm tasarlamam gerektiine karar verdim. Bu amacm gerekletirebilmek amacyla aadaki ok ksa uygulamay yazdm. import java.awt.*; public class IlkPencere { public static void main(String args[]) { Frame pencere=new Frame("ILK PENCEREM"); pencere.setLocation(0,0);

265

pencere.setBackground(Color.red); pencere.setVisible(true); } } Yazdm bu java dosyasnn derledikten sonra altrdm. Karmda beni bekleyen gzel bir pencere olaca dncesindeydim. Gerektende muazzam bir pencere oluturmay baarmtm :)

Doruyu sylemek gerekirse daha byk bir frame olacan dnmtm. Bunun zerine yazm olduum kod satrlarn incelemeye baladm. lk olarak awt.window paketinde yer alan Frame snfndan bir nesne rnei oluturmutum. Bunu yaparkende, yapc metoda string tipte bir parametre gnderdim. Bu parametre Frame penceresinin bal (Title) olacakt. Frame pencere=new Frame("ILK PENCEREM"); Daha sonra, Frame in ekran zerindeki konumunu belirledim. Bunun iinde setLocation metoduna X ve Y koordinatlarn 0 olarak verdim. Bylece, Frame penceresi ekrann sol st kesinde konumlanacakt. pencere.setLocation(0,0); setBackgorund metodu ile Frame penceresinin arka plan rengini krmz olarak belirledim. pencere.setBackground(Color.red); Frame snfnn en nemli metodu ise setVisible idi. Bu metod, oluturulan Frame penceresinin gsterilmesini salyordu. Bunun iin parametre olarak metoda true deerini vermek yeterliydi. pencere.setVisible(true);
266

Buraya kadar herey sorunsuz gzkyordu. Ancak Frame in neden byle grndn tam olarak anlayamamtm. Kaynaklarm gzden geirdiimde, setSize isimli metodu kullanmadm farkettim. Bu metod ile Frame in balang boyutlarn belirleyebiliyordum. imdi tek yapmam gereken uygulama koduna setSize metodunu ilave etmek olacakt. Lakin ufak bir sorun vard. O da, Frame penceresini X butonuna basp kapatamyor oluuydu. Programdan kamyordum. Bunun tek bir nedeni olabilirdi o da, X butonu ile kapatma ilemi iin gerekli olan olay dinleyecisinin ilgili olay metodunu altrmayyd. Frame snfnn olaylarna sonradan zaten bakacaktm. Ancak bu pencereyi bir ekilde kapatp, kodumu dzenlemek istiyordum. Yaklak bir yarm saat kadar srf bu pencerenin nasl kapatlacan aratrdm. Nitekim windows un ALT+F4 tu kombinasyonu dahi ie yaramyordu. Sonunda komut satrndan CTLR+C tu komimasyonuna basmam gerektiini rendim. Bu tu kombinasyonu sayesinde ak olan uygulama kapatlabiliyordu. Artk uygulama kodlarm dzenleyebilir ve Frame penceresinin istediim boyutlarda oluturulmasn salayabilirdim. Bu amala kodlarma aadaki satr ekledim. Burada ilk parametre Frame penceresinin geniliini (width), ikinci parametres ise yksekliini (height) belirtmekteydi. pencere.setSize(300,100); Uygulamay bu haliyle derleyip altrdmda 300 piksel geniliinde ve 100 piksel yksekliinde bir Frame penceresi elde ettim. Artk hem Title grnyordu, hemde Frame penceresi daha makul boyutlardayd.

Kaynaklardan Frame ile ilgili olarak kullanabileceim dier teknikleride aratrmaya baladm. rnein, X butonunun aksine, Minimize ve Maksimize butonlar alyor dolaysyla Frame penceresi mimimize edilebiliyor yada maksimize
267

olabiliyordu. Derken aklma, bu Frame in Maksimize edilmek istendiinde, belirli ykseklik ve geniliin stne kmamasn nasl salayabileceim sorusu geldi. Bunun iin setMaximizedBounds() isimli bir metod buldum. Bu Frame snfna ait metoda Rectangle snf trnden bir nesne parametre olarak aktarlabiliyordu. Bu Rectangle nesnesi, bir dortgen eklini boyutlar ve konumlar ile bildirebildiinden, setMaximizedBounds metodu sayesinde, Frame penceresi belirtilen Rectangle nesnesinin boyutlar kadar byyebilecekti. Hemen bu durumu analiz etmek amacyla uygulama kodlarn aadaki gibi gelitirdim. Rectangle r=new Rectangle(500,500); pencere.setMaximizedBounds(r); Burada Rectangle snfndan nesne rneini olutururken, parametre olarak genilik ve ykseklii bildirdim. lk parametre Rectangle nesnesinin geniliini, ikinci parametre ise yksekliini belirtmekteydi. Daha sonra, setMaximizedBounds metoduna, bu Rectangle nesnesini parametre olarak verdim. Uygulamay tekrar derleyip altrdmda ve Maksimize butonuna bastmda, Frame in 500 piksel X 500 piksel boyutlarna geldiini grdm. Normal artlar altnda bu metodu kullanmasaydm, Frame tm ekran kaplayacak ekilde boyutlandrlacakt. Frame pencereleri ile ilgili aklma taklan bir dier nokta ise, X butonu ile pencereyi kapatamaymd. Bunu kendim programlamam gerekiyordu. Bir baka deyile, olay metodunu yazmalydm. Kaynaklarm aratrdmda, Java Frame snfnn aadaki window olay metodlarna cevap verebildiini rendim. Frame iin Window Olaylar windowOpened windowClosing Pencere ilk kez gsterildiinde alan olay. Pencere kullanc tarafndan kapatlrken gerekleen olay. WindowListener Arayznden

268

windowClosed windowIconified windowDeiconified

Pencere kapatldktan sonra alan olay. Pencere minimize edildiinde gerekleen olay. Minimize olan bir Pencere normal haline dndnde gerekleen olay. Pencereya odaklanld (Focus) yani aktifletirildii zaman alan olay. Pencereden ayrlndnda alan olay. Focus (odak) pencereden uzaklatnda alan olay. Odak (Focus) pencereye geldiinde alan olay.

windowActivated

windowDeactivated windowLostFocus windowGainedFocus

WindowFocusList Arayznden

Pencerenin durumu deitiinde windowStateChanged (minimize edildiinde, maksimize edildiinde vb.) alan olay.

WindowStateList Arayznden

lk olarak denemek istediim, pencerenin X butonu ile kapatlabilmesiydi. ncelikle, windowClosing metodunu uygulamam gerekiyordu. Bunu gerekletirebilmek iin, WindowListener arayzn snfa uygulamalydm. Bylece, WindowListener arayznden uyguladm windowClosing metodunda yazabilir ve X butonu ile pencerenin kapatlamas srasnda oluacak olay kodlayabilirdim. Bu amala snf kodlarn aadaki gibi gelitirdim. import java.awt.*; import java.awt.event.*; public class IlkPencere implements WindowListener { public static void main(String args[]) {

269

IlkPencere p=new IlkPencere(); Frame pencere=new Frame("ILK PENCEREM"); pencere.setLocation(0,0); pencere.setBackground(Color.red); pencere.setSize(300,100); Rectangle r=new Rectangle(500,500); pencere.setMaximizedBounds(r); pencere.addWindowListener(p); pencere.setVisible(true); } public void windowClosing(WindowEvent e) { System.exit(0); }

Program bu haliyle derlediimde aadaki hata mesajn aldm.

Anladm kadar ile WindowListener arayzndeki tm window olay metodlarn snf ierisinde kullanmasamda bildirmeliydim. Bu amala snfa aadaki metodlarda ekledim. public void windowOpened(WindowEvent e) { } public void windowClosed(WindowEvent e) { } public void windowIconified(WindowEvent e) {

270

} public void windowDeiconified(WindowEvent e) { } public void windowActivated(WindowEvent e) { } public void windowDeactivated(WindowEvent e) { } Uygulama baarl bir ekilde derlendikten sonra, hemen X butonu ile kapatlp kapatlamadn denemedim. Sonu baarlyd. Elbetteki bir pencere bu haliyle ok yavan durmaktayd. Bu pencereye kontroller eklemek gerekiyordu. Normal bir Applet e kontroller nasl ekleniyorsa buradada ayn kurallar geerliydi. Bu kez bir Applet e kontrol eklemek yerine bir Frame nesnesine kontrol ekleyecektim. Bu amala uygulamay biraz daha dzenlemeye ve ilgin hale getirmeye karar verdim. Amacm Frame iindeki bir button yardmyla baka bir frame penceresinin alabilmesini salamakt. Bu amala aadaki rnei oluturdum. import java.awt.*; import java.awt.event.*; public class IlkPencere implements WindowListener,ActionListener { public Frame p1; public Button btnIkinciPencere; public Button btnKapat; public int X; public int Y; public void PencereAyarla(String baslik,int genislik,int yukseklik,int konumX, int konumY,Color arkaPlanrengi) { X=konumX;

271

Y=konumY; p1=new Frame(baslik); p1.setLocation(konumX,konumY); p1.setBackground(arkaPlanrengi); p1.setSize(genislik,yukseklik); p1.setLayout(new FlowLayout()); p1.addWindowListener(this); btnIkinciPencere= new Button("Ikinci Pencere"); btnKapat=new Button("Kapat"); p1.add(btnIkinciPencere); p1.add(btnKapat); btnKapat.addActionListener(this); btnIkinciPencere.addActionListener(this); p1.setVisible(true); } public static void main(String args[]) { IlkPencere p=new IlkPencere(); p.PencereAyarla("ANA PENCERE",250,100,0,0,Color.white); } public void actionPerformed(ActionEvent e) { if(e.getSource()==btnKapat) { p1.setVisible(false); } else if(e.getSource()==btnIkinciPencere) { IlkPencere p=new IlkPencere(); X=X+50; Y=Y+50; p.PencereAyarla("ANA PENCERE",100,100,X,Y,Color.red);
272

} public void windowClosing(WindowEvent e) { System.exit(0); } public void windowOpened(WindowEvent e) { } public void windowClosed(WindowEvent e) { } public void windowIconified(WindowEvent e) { } public void windowDeiconified(WindowEvent e) { } public void windowActivated(WindowEvent e) { } public void windowDeactivated(WindowEvent e) { } } Bu uzayp giden kodlar ok ie yaramyor. Ancak u ana kadar GUI ler ile ilgili bilgilerimi tekrar etmemede yardmc oldu. Bu uygulama altnda ilk olarak belirtilen boyutlarda, konumda, balkta ve art alan renginde bir ana pencere oluturuyor. Bu pencere zerine, FlowLayout snfnn ngrd Layout dzenine gre yerleen iki Button bileenim var. Iknci Pencere balkl button bileenine tklandnda yeni bir pencere oluturuluyor. Kapat button bileeni ise, bu pencereyi kapatyor. Bu kapatma ileminde setVisible(false) metodunu kullandm. Bylece sonradan alan pencereler aslnda gizleniyordu. Uygulamay bu haliyle derleyip altrdmda aadaki gibi bir grnt olutu. Her yeni pencere bir ncekinin konumunun 50 birim sana ve altna konumlandrlyor. Elbette X butonuna
273

basldnda System.exit(0) metodu o an alan prosesi sonlandrd iin tm pencereler kapanmaktayd. Mesela ilk pencerede Kapat balkl butona basnca komut satr ak kalacak ekilde pencere ortadan kayboluyor. Yani grnmez oluyor. Ancak proses almaya devam ediyor. Sanrm neden ie yaramaz bir program olduu ortada. Olsun en azndan el cimnastipi yapm oldum.

u anada kadar yaptklarm ile gelitirdiim bu pencere uygulamalarnda nemli bir sorun var aslnda. Bu uygulamalar altrabilmek iin komut satrnda ilgili snf java yorumlaycs ile amam gerekiyor. Dier taraftan uygulama alrken, komut satr ak kalyor. Oysaki normal bir exe dosyas gibi bu uygulamann tek bana alabilmesi ok daha yerinde olur. te bunu gerekletirmek iin kaynaklarda 3 yoldan bahsedildiini rendim. En basit olan nc parti yazlmlar ile bu ii gerekletirmek. rnein halen daha zlemini ektiim deerli arkadamn bilgisayarnda yer alan JBuilder gibi. Dier iki yol ise bizim manuel olarak kullanabileceimiz teknikler ieriyor. Bunlardan birisi Dos ortamndan kalma bat(batch) uzantl dosyalar ierisine uygulamay altracak kod satrn yazmak. Dieri ise, GUI uygulamasna ati tm snflar ve gerekli dosyalar ieren bir JAR paketi oluturmak. Akas JAR paketini oluturmak bana daha mantkl grnd. Ancak bir JAR paketini oluturmadan nce, bu JAR paketi iin verisyon numaras, ana snf gibi bilgileri ieren bir manifesto
274

dosyas hazrmamam gerektiini rendim. Bu manifesto dosyas, mf uzantl olmakla birlikte, aslnda .net assembly larndaki manifesto bilgilerinin tutulduu yapya benzer bir ierie sahip. ok basit olarak gelitridiim java uygulamas iin aadaki bilgileri ieren bir manifesto dkman hazrladm. Manifest-Verison: 1.0 Main-Class: IlkPencere Created-By: 1.4.1 (Sun Microsystems Inc.) Bu dosyay Manifesto.mf ile kaydettikten sonra aadaki komut ile, Jar dosyasn oluturdum.

Artk Pencereler.Jar dosyasna ift tkladmda GUI uygulamasnn, normal bir windows uygulamas gibi altn grdm. Bu sorunu zmem son derece nemli idi. Artk windows tabanl GUI lerin nasl oluturulduunu, window olaylarna nasl cevap verdiini biliyordum. Dahas bu pencereler zerine awt bileenlerinin nasl ekleneceini ve hereyden nemlisi bu GUI uygulamasnn ift tklamal versiyonunun Jar dosyas olarak nasl hazrlanabileceini biliyordum. Artk tm bu bildiklerimi birletirerek daha ie yarar bir uygulama yapabileceim kansndaydm. Bunun iin aklma basit bir hesap makinesi uygulmas yazmak geldi. Ama ok basit. Sadece 2 operand deeri iin 4 ilem yapacakt. Lakin burada nemli olan, Frame in tasarlanmas ve Frame zerindeki bileenlerin olaylara tepki vermesinin salanmasyd.
275

Hemen kollar svadm ve uygulamay gelitirmeye baladm. Sonuta hem pratik yapm oldum hemde GUI bilgilerimi tekrar etmi. Sonuta aadaki kk programck ortaya kt. import java.awt.*; import java.awt.event.*; /* HesapMakinesi snfnda window olaylarna ve Button olaylarna izin verebilmek iin, WindowListener ve ActionListener arayzlerinin uygulanmas gerekir. */ public class HesapMakinesi implements WindowListener,ActionListener { /* Frame snfna ait nesne tanmlanyor ve bu Frame zerindeki awt bileenleri tanmlanyor.*/ public Frame f; public Button btnHesapla; public Label lbSayi1; public Label lbSayi2; public Label lbIslem; public TextField tfSayi1; public TextField tfSayi2; public Choice lstIslem; /* iki say deerini ve ilem sonucunu tutacak double tipinden deikenler tanmlanyor.*/ public double sayi1,sayi2,sonuc; /* Olustur metodunda, penceremiz ve zerindeki bileenler oluturuluyor.*/ public void Olustur() { f=new Frame("Hesap Makinesi"); // Bal (Title) Hesap Makinesi olan bir Frame nesnesi oluturuluyor. f.setLayout(new FlowLayout()); // Frame zerindeki bileenler FlowLayout tekniine gre dizilecekler. Color c=new Color(248,221,139); /* Color tipinden bir nesne R (Red), G (Green), B(Blue) formatnda oluturuluyor.*/ f.setBackground(c); // Pencerenin arka plan rengi c isimli Color nesnesine gre belirleniyor.

276

/* TextField bileenleri 10 karakter uzunluunda oluturuluyor.*/ tfSayi1=new TextField(10); tfSayi2=new TextField(10); /* Label bileenleri balklar ile oluturuluyor.*/ lbSayi1=new Label("Sayi 1"); lbSayi2=new Label("Sayi 2"); lbIslem=new Label("ISLEMIN SONUCU..."); /* Button bileeni oluturuluyor ve bu bileen iin olay dinleyicisi ekleniyor.*/ btnHesapla=new Button("Hesapla"); btnHesapla.addActionListener(this); /* Choice (baka bir deyile ComboBox) bileeni oluturuluyor. Listedeki elemanlar addItem metodu ile ekleniyor.*/ lstIslem=new Choice(); lstIslem.addItem("TOPLA"); lstIslem.addItem("CIKART"); lstIslem.addItem("BOL"); lstIslem.addItem("CARP"); /* Bileenler srasyla Frame bileenine yani pencereye add metodu ile ekleniyor. */ f.add(lbSayi1); f.add(tfSayi1); f.add(lstIslem); f.add(lbSayi2); f.add(tfSayi2); f.add(btnHesapla); f.add(lbIslem); f.pack(); /* pack metodu ile pencerenin ykseklii ve genilii, ierdii bileenlerin kaplad alana gre otomatik olarak ayarlanyor.*/ f.addWindowListener(this); // Frame bileeni iin window olay dinleyicisi ekleniyor.

277

f.setVisible(true); // Frame bileeni (pencere) gsteriliyor.

/* IslemYap metodunda 4 ilem gerekletiriliyor. */ public void IslemYap() { sayi1=Double.parseDouble(tfSayi1.getText()); /* TextField bileenlerinin string ierii Double snfnn parseDouble metodu ile double tipine dntrlerek deikene atanyor.*/ sayi2=Double.parseDouble(tfSayi2.getText()); /* if koullarnda Choice bileeninde seili olan item getSelectedItem() metodu ile alnyor ve uygun olan ilemler yaplyor.*/ if(lstIslem.getSelectedItem()=="TOPLA") { sonuc=sayi1+sayi2; bIslem.setText(sayi1+"+"+sayi2+"="+sonuc); } else if(lstIslem.getSelectedItem()=="CARP") { sonuc=sayi1*sayi2; lbIslem.setText(sayi1+"x"+sayi2+"="+sonuc); } else if(lstIslem.getSelectedItem()=="CIKART") { sonuc=sayi1-sayi2; lbIslem.setText(sayi1+"-"+sayi2+"="+sonuc); } else if(lstIslem.getSelectedItem()=="BOL") { sonuc=sayi1/sayi2; lbIslem.setText(sayi1+"/"+sayi2+"="+sonuc); } } public static void main(String args[]) { HesapMakinesi m=new HesapMakinesi();

278

} /* actionPerformed olay meydana geldiinde bu metod alyor.*/ public void actionPerformed(ActionEvent e) { if(e.getSource()==btnHesapla) // Eer olayn kayna Button bileeni ise, yani Button a tklandysa. { IslemYap(); } } /* Kullanc X buton ile pencereyi kapatmak istediinde bu olay metodu alyor. */ public void windowClosing(WindowEvent e) { System.exit(0); /* Gncel olan proses sonlandrlyor. Dolaysyla uygulama sona eriyor. */ } public void windowOpened(WindowEvent e) { } public void windowClosed(WindowEvent e) { } public void windowIconified(WindowEvent e) { } public void windowDeiconified(WindowEvent e) { } public void windowActivated(WindowEvent e) { } public void windowDeactivated(WindowEvent e) { } }

m.Olustur();

279

Program derledikten sonra Manifesto dosyasn (ManifestoHesapMakinesi.mf) aadaki gibi dzenledikten sonra, JAR Paketinide hazrladm. Manifest-Verison: 1.0 Main-Class: HesapMakinesi Created-By: 1.4.1 (Sun Microsystems Inc.)

Paketi ift tkladmda, basit hesap makinesi uygulamam kullanlmaya hazrd.

Artk GUI lerde iyice ilerlemeye baladm hissediyordum. Bununla birlikte, 2 boyutlu grafik izimleri, animasyon hazrlamak, resim ilemek, ses ilemek, Swing bileenleri, Menu ler vs... gibi henz bilmediim daha pek ok konu vard. Ancak hem kahvem hemde pilim bitmiti. Sanrm nmzdeki gnlerde, bu konulara eileceim.

Blm 19: JBuilder ile Database Uygulamalar Bu hafta olduka mutluyum. Nitekim, JBuilder programn kullanan arkadam tatilden dnd. lk frsatta ona uramay ve JBuilder ile yeni bir eyler yapmay dnyordum. Ofisten ieri girdiimde, arkadam beni grnce hafif bir tebessm ile yle dedi; "Bir kahve molas veriyoruz ha!". Bam hafife ne emem, ofise geli amacm aka ortaya koymutu. Ksa bir
280

muhabbetin ve gzel yaz tatili servenlerinin ardndan, arkadamn bilgisayar ve JBuilder ile ba baa kalmtm. Uzun sredir merak ettiim bir uygulamay gelitirmek istiyordum. Bir veritaban uygulamas. Akas JBuilder ile bu tarz bir uygulamann nasl yazlacan merak ediyordum. Bundan bir ka sene ncesine kadar bir Delphi programcs olmam, Borland firmasnn yazlm gelitirme uygulamalarna olan ainalm arttran bir etken olmutu. Delphi programlama dilinin bana verdii en nemli kazan, gelimi bileen paketleri sayesinde, patronun benden istedii uygulamalar zamanndan ok nce gelitirebilmem olmutur. JBuilder uygulama gelitirme ortam iinde ayn eyin sz konusu olduundan emindim. Nitekim bu bir yandan iyi, dier yandanda kt bir olgudur. Delphi gibi gelitirme ortamlar, bir programcnn analitik dnce sistemini ve kod yazma alkanlklarn tembelletirir. Zaten bu bu .net platformuna geip C# dilini renmemin nedenlerinden sadece birisiydi. Ancak, yinede zaman zaman uygulama gelitirirken Visual Studio.Net ortamn kullanmakta ve avantajlarndan yararlanmaktaym. Buna ramen, Visual Studio.Net, programcy daha ok kod yazmaya ve algoritma gelitirmeye davet ederek daha bilgili olmamz gerektiriyor diyebilirim. Sonu olarak yinede, JBuilder gibi bir gelitirme ortamn kullanarak neler yaplabileceinide grmekte fayda var. zellikede youn projelerde alanlar iin, uygulama gelitirme sresinin ksaltlmas son derece nemli bir faktr. Ben bu dncelerim ile bouurken bir anda kendimi, JBuilder ile veritaban uygulamas gelitirirken bulmutum. ncelikle, iin nasl yapldn kavramam gerekiyordu. Bu amala JBuilder n tutorial larnda biraz inceleme yaptm. Daha sonra ise uygulamay gelitirmeye baladm. Hereyden nce bana, kullanabileceim bir veritaban gerekliydi. Bunu gerekletirebilmek iin, yerel sql sunucusu zerinde yer alan Northwind veritabani altnda personel isimli bir tablo oluturdum.

281

Personel tablosunda, personelin saat creti ve alt sre ile isim ve soyisim bilgileri yer almakta. Aslnda bu tabloda toplam cretin yer ald bir stunda oluturulabilirdi. Ancak ben bu stunu, JBuilder uygulamas iinde bir calculated field olarak oluturmay planlyorum. Personel tablosunu bu ekilde oluturduktan sonra, bir ka satrda veri girdim. Artk JBuilder uygulamasn gelitirmeye balayabilirdim. lk yapmam gereken, bir Java Projesi amakt. Projemi sihirbaz admlarn izleyerekten ksa bir srede oluturdum. nce birinci adm,

282

Sonra ikinci adm,

283

Son olarakta nc adm,

284

Buraya kadar yaplan ilemler, JBuilder ile oluturduum Applet uygulamasndaki admlar ile aynyd. Srada, uygulama tipini semem ve oluturmam vard. Bu sefer, windows zerinde alacak bir uygulama gelitirmek istiyordum. Bu nedenle, File>New mensnden alan Object Gallery iletiim penceresindeki General ksmndan Application ablonunu setim.

285

Elbette setiim Application ablonu iin belli admlar ilemem gerekiyordu. Karmdaki sihirbaz admlarnda hzl bir ekilde gerekletirerek yoluma devam ettim. nce ilk adm,

Arndan ikinci adm,

286

Ardndan nc ve son adm.

287

Application iin gerekli Frame de oluturulduktan sonra, ilk yaptm i, Frame in Layout zelliini XYLayout olarak ayarlamak oldu. Nedense bu Layout lardan ok ektim Java da. Ancak JBuilder benim iin esnek bir zm salamt. XYLayout ile, bileenlerimi frame zerine bamsz bir ekilde yerletirebilmekteydim. Bu admlara ramen halen daha veritaban uygulamasn yazmaya balayamamtm. lk olarak neye ihtiyacm olduunu dndm. Net ortamnda uygulama gelitirirken, veritabanna doru bir balant hattn tesis etmeme yardmc olacak Connection nesnelerini kullanyordum. lk nce bileenler paletinde, bu tarz bir e aradm. DataExpress sekmesindeki Database bileeni bu araymn cevab oldu. Bu bileen ile, balanmak istediim veritabanna bir hat ekebileceimi dnyordum.

Hemen Database bileenini Frame zerine izdim ve zelliklerine baktm. Connection zelliine tkladmda, balant
288

ayarlarn yapabileceim, Connection iletiim penceresi ile karlatm. Bu iletiim penceresinde yer alan Driver ksmnda, sistemdeki veritabanlarna eriimimi salayacak eitli java veri srclerinin olduunu farkettim. Ancak bunlardan bazlar krmz font ile yazlmlard. Sonradan, krmz font ile yazlm veri srclerinin sistemde ykl olmadn anladm. Elimde, kullanabileceim JdbcOdbcDriver srcs vard. Bu src ile sistemdeki ODBC kaynaklarna balanabilirdim.

Bu srcy setikten sonra ise, URL ksmna girdim. Ancak tabiki, sql sunucusunda yer alan Northwind veritaban iin bir System DSN i tanmlamadmdan, Northwind veritabanm bu listede grnmyordu. Hemen Administrative Tool ksmndan, ODBC ayarlarna girdim ve sqlBaglanti isimli bir System DSN ini oluturdum. Tekrar, JBuilder ortamna dndmde, URL sekmesinde, henz oluturduum System DSN inin eklendiini farkettim.

289

Bu ilemlerin ardndan Test Connection butonua basarak balantnn baarl bir ekilde salanp salanmadna baktm. Artk veritabanma stelikte yerel makinedeki sql sunucusuna balanabileceim bir Database bileenim olmutu. imdi ise, bu veritabanndaki Personel isimli tabloda yer alan verileri bir ekilde uygulama ortamna ekmem gerekiyordu. Bunun iin bir sql query si kullanabilirdim. Ancak bu sql query sini altracak ve bir veri kmesi olarak ortama aktaracak bir bileene ihtiyacm vard. Kaynaklarmdan yaptm incelemelerden sonra, DataExpress sekmesinde yer alan QueryDataSet bileeninin aradm kontrol olduunu rendim.

Bu bileenin en nemli zellii, query zelliiydi. Query zelliine girdiimde, Query iletiim penceresi ile karlatm. Bu iletiim penceresinde, kullanacam balanty salayan database bileenini setim. Bylece query bileenime, hangi veritaban zerindeki tablolar ile alacan belirtmi oluyordum.
290

Query bileeninin, kullanaca sorguyu, SQL Builder sekmesinden seebileceim gibi, direkt olarak SQL statement ksmnada yazabilirdim. SQL Builder ksm, sql sorgusunu kolayca ve detayl bir ekilde hazrlayabileceim bir seenek sunuyordu. Burada filtreleme, gruplama, sralama ve sorgunun testi gibi ilemleri kolayaca gerekletirebileceim admlar yer almaktayd.

291

Sonu olarak burada oluturduum sql cmlecii aadaki gibi olmutu.

292

Test Query butonua tklayarak sorguyu test ettim. Sorgunun baarl bir ekilde altrlabildiini gsteren Success ibaresinden sonra ilemlerime devam etmeye hazrdm. Buradaki query seenekleri arasnda nemli olanlarndan bir tanesi da, "Execute query immediately when opened" ibaresiydi. Bu seenein iaretli olmas ile, uygulama almaya baladnda query nin otomatik olarak yrtlmesi ve queryDataSet bileeni ile bal olan kontrollerin dolmas salanyordu. Bu admlardan sonra, srada uygulamaya ait Frame bileenlerinin oluturulmas vard. Bu amala dbSwing sekmesi altndaki bileenleri kullanabilirdim. lk olarak, Delphi zamanlarndan aklmda kalan bir bileeni Frame e yerletirmeye karar verdim. JdbNavToolBar. Tabi delphi de bu bileenin ad farklyd ama ekil itibariyle neredeyse aynyd. Bu bileen, ekilen veri kmesi zerinde gezinmemi, yeni satrlar eklememi, satrlar dzenlememi, gncellememi vb... ilemleri kolayca yapmam salayacakt.

Bileenimi Frame zerine ekledikten sonra yapmam gereken tek ey, dataSet zelliine, queryDataSet1 bileenini atamak oldu. Bylece, navigator bileenimi, ilgili veri kmesi ile ilikilendirmitim. Bu admda tamamladktan sonra, Frame zerine Personel tablosundaki satr verilerini gsterecek dbTextField ve dbLabel bileenlerini ekledim. Bu db bileenlerininde query zelliklerine, queryDataSet1 bileenini atadm. Dier yandan, bu bileenlerin hangi stunlardaki verileri gstereceini belirlemek amacyla dataColumn zelliklerinede ilgili Column isimlerini atadm. rnein, PersonelAd stunu iin;

293

Sonu olarak Frame tasarmm aadaki gibi olmutu.

Artk uygulamam altrabilirdim. Bunun iin sabrszlanyordum. Hemen ie koyuldum ve uygulamay Run ettim. Uygulama alyordu, satrlar arasnda gezinebiliyordum. E zamanl olarakta, bileenler iindeki veriler deiiyordu.

294

Derken hemen yeni bir kayt eklemek istedim. Bunun iin tek yapmam gereken navigator bileenindeki + iaretine basmakt. Bunu nerden mi biliyordum. Delphi deki Navigator bileeninden tabiki. Ancak, karma beklenmedik bir hata mesaj geldi. Sorun Personel tablosundaki PersonelID stunundayd. Bu stunu, Primary Key olarak belirlemitim ve otomatik artan bir deere gre gncellenmesini ayarlamtm. Yani, deerini sql sunucusunun kendisi otomatik olarak belirliyor ve benzersiz olmak artyla arttryordu.

Hemen hata mesajnda belirtilen deiiklikleri yaptm. queryDataSet1 bileeninin, MetaDataUpdate zelliindeki RowID seeneinin iaretini kaldrdm.

295

Daha sonra ise, PersonelID stununun zelliklerinden, rowID zelliinin deerini true olarak deitirdim. Bu ilemlerden sonra, uygulamam tekrar altrdmda artk kayt ekleyebiliyor, gncelleyebiliyor ve silebiliyordum. Ancak yapm olduum bu deiiklikler, sadece queryDataSet bileenin temsil ettii veri kmesi zerinde gerekleiyordu. Yani balantsz katman zerinde. Asl veri tablosuna bu deiikliklerin yanstlabilmesi iin, Navigator bileenindeki Save Changes ipucu textine sahip butonun tklanmas gerekiyordu. imdi ise sra calculated field n oluturulmasna gelmiti. Amacm, Saat cretleri ile alma srelerinin arpmn veren bir calculated field oluturmakt. Bunu gerekletirebilmek iin ncelikle yeni bir alana ihtiyacm vard. Bu alan Personel tablosu zerinde deil, queryDataSet bileeni zerinde oluturulacakt. Baka bir deyile alma zamannda oluturulacak ve offline olarak alacakt. Bu alan ekleyebilmek iin, queryDataSet1 bileenine ift tklayarak alan penceredeki + butonunu kullandm.

296

Yeni alann columnName zellii ile ismini, caption zellii ile baln, name zellii ilede bileen adn belirttikten sonra, dataType zelliinide BIGDECIMAL olarak belirledim. Nitekim Sql sunucusunda decimal olarak belirtilen veri tipi, java ortamnda BIGDECIMAL olarak eletirilmekteydi. Bunlara ek olarak, calcType zelliinide calculated olarak deitirmem gerektiini uygulamay bu haliyle derlediim zaman aldm hata mesajlarndan anladm. Bu zelliide dzenledikten sonra artk tek yapmam gereken, queryDataSet1 bileeninin calcFields olayn kodlamak olacakt. Bu olay metodu, calculated field lar iin gerekli hesaplamalarn yapld yerde devreye girmekteydi. Buradaki kodlar aadaki gibi oluturdum. void queryDataSet1_calcFields(ReadRow changedRow, DataRow calcRow, boolean isPosted) { java.math.BigDecimal saat=chancedRow.getBigDecimal("SaatUcreti"); java.math.BigDecimal sure=chancedRow.getBigDecimal("CalismaSuresi"); java.math.BigDecimal toplamUcret = saat.multiply(sure); calcRow.setBigDecimal("ToplamUcret",toplamUcret);

297

} Bu kodlarda ilk dikkati eken nokta, chancedRow parametresi ile gncel satr bilgisine eriilmesiydi. lk olarak, SaatUcreti ve CalismaSuresi alanlarnn deerlerini, ReadRow snfndan bir rnek olan chancedRow parametresinin getBigDecimal metodu ile, BigDecimal trnden bir deikene aktaryorduk. Sonra ise ilgin bir kod satr altrlyordu. Nitekim normal artlar altnda iki deikeni arpmak istediimde bildiim arpma operatrn kullanrdm. Ancak burada aadaki kod satrn yazdmda, java.math.BibDecimal toplamUcret = saat * sure; * operatrnn, BigDecimal tipine uygulanamyaca syleyen bir derleme zaman hatas alyordum. Bunun zerine kaynaklarm ksa bir sre aratrdmda, BigDecimal tipindeki deikenlerden birisine multiply metodunu kullanarak, arpma ilemini gerekletirebileceimi kefetmitim. Calculated field alannn deerine hesaplanan deeri aktarmak iin, bu alan temsil edecek DataRow snfnn bir rnei olan calcRow parametresinin setBigDecimal metodunu kullandm. Bu ilemlerin ardndan, hesaplanan alana ait bilgilerin ekranda gsterilmesini salamak amacyla Frame zerine, bir JdbLabel bileeni ekledim. Uygulamam altrdmda, ToplamUcret alannn her bir satr iin hesaplandn ve yaplan gncellemelerdende etkilendiini farkettim. Bu basit uygulama sorunsuz alyordu. stelikte 4 satr kod yazmama ramen.

298

Elbetteki bir veritaban uygulamasnda yaplabilecekler sadece bunlar ile snrl deildi. rnein, buradaki bileenleri kullanmadan, JDBC snflar yardmyla bu ilemler nasl gerekletirilebilirdi? Yada bir stored procedure nasl altrlabilirdi ? Hatta arama, filtreleme gibi ilemler iin kodlar nasl dzenlemek gerekiyordu? Bu gibi konular incelemeye frsat kalmadan saatin epeyce ilerlediini ve arkadamn ofisi kapamak zere olduunu farkettim. Uzun sre boyunca beni izlemi ve bilgisayar banda nasl kendimden getiimi seyretmiti. Sonuta konsantremi bozmak istememiti ama saatin gece yarsn getiinide birisinin bana sylemesi gerekiyordu. "Artk bir sonraki kahve molasna kadar dinlenmelisin" dediinde, itiim kahve bardaklarnn masa banda uzunca bir kuyruk oluturduunu farketmitim. lerleyen haftalar, JDBC ile ilgili yeni aratrmalarn habercisiydi.

Blm 20: JBuilder ile Database Uygulamalar 2 Getiimiz hafta boyunca, JBuilder ortamnda veritaban uygulamalarnn bileenler yardmyla kolay bir ekilde nasl oluturulabileceini inceledim. Bu hafta ise, temel tablo

299

ilemlerini kod yazmak suretiyle nasl gerekletirebileceimi aratrdm. JDBC olduka geni kapsama sahip bir konuydu. Hatta geni demek yetmez tam anlamyla bir okyanus olduunu syliyebilirim. Nasl ki Ado.Net hakknda yazlm kaln, devasa kitaplar var ise, JDBC iinde ayn durumun sz konusu olduunu biliyordum. Ancak en azndan elimdeki kaynaklardan faydalanarak temel bir ka tablo ileminin nasl gerekletirilebileceinide incelem taraftarydm. Bana gerekenler temel sql bilgisi ve JDBC nin bu iler iin hangi snflar kullandyd. Sonu olarak aadaki tarzda bir vizyon edinmeyi baarabildim. Basit bir veritaban uygulamas iin gerekli unsurlar bunlard. Bir JDBC srcs, geerli bir balant, alan bir sql cmlecii ve veri kmesini ekebileceim bir bileen.

Yapmam gereken son derece basitti. Uygulamam iin geerli bir JDBC Driver ykleyecek sonra bu driver kullanarak,

300

sistemdeki odbc kaynaklarna balanabilecek bir Connection nesnesi oluturacaktm. Daha sonra bu Connection nesnesini kullanan bir Statement nesnesi yaratacak ve bu nesneyi, tablodaki verileri ekmeme yardmc olacak bir sql cmlecii ile altracaktm. Statement nesnesi, Ado.Net teki SqlCommand nesnesine ok benziyordu. Her ikiside sql cmleciklerini altrmak amacyla kullanlabiliyorlard. Sql cmleciinin altrlmas sonucu oluacak veri kmesini ise ResultSet snfndan bir nesne rneine aktaracaktm. Bu dnceler eliinde kahvemden bir yudum aldm ve uzun sre monitore bakakaldm. Nitekim ne yapacam biraz olsun anlamama ramen nasl yapacam henz kestirememitim. Elbetteki, kaynaklarm ba ucumda duruyordu. Ancak zellikle JDBC ile ilgili olan kitaplar tam anlamyla kaln sayfa saylar ile korkulu bir rya gibiydiler. Kaynaklar arasnda geziniyor ve en basit haliyle nasl gelitireceimi aratryordum. O kitap bu kitap derken uzun saatler sonras bir eyler kartmay baarmtm. Bu aratrma yaklak olarak 3 gn, geceli gndzl srdrdm. Geceleri biraz uyuduumu itiraf edeyim ama. Halen daha da tam olarak olaya vakf olabilmi deildim. Ancak uygulamam nasl gelitirebileceimi en azndan biliyordum. Hemen arkadamdan dn aldm JBuilder Demo cd si ile kurduum JBuilder uygulamasn atm. Kodlarm JBuilder zerinde yazacaktm. Nitekim hem tasarm ile az uramak hemde JBuilder n intellisense zelliklerini kullanmak istiyordum. Tabi JBuilder n geni yardm ieriide iin dier cazip tarafyd. ncelikle yeni bir Proje atm, bu projeye bir Application ekledim ve temel olarak aadaki gibi bir Frame oluturdum.

301

Uygulamada yapmak istediklerim ilk bata, Sql sunucusunda yer alan Personel tablosundaki verileri ResultSet nesnesi iine doldurmak ve sonra bu kayt kmesindeki satrlar arasnda navigasyon tular yardmyla gezinmekti. lk olarak Doldur balkl button bileenine basldnda altrlacak olay kodlarn yazdm. public java.sql.ResultSet rsPersonel; public java.sql.Connection conPersonel;

void btnDoldur_actionPerformed(ActionEvent e) { try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); conPersonel = java.sql.DriverManager.getConnection( "jdbc:odbc:sqlBaglanti"); java.sql.Statement sqlPersonel = conPersonel.createStatement(java.sql.ResultSet.TYPE_SCROLL_SENSITIVE java.sql.ResultSet.CONCUR_UPDATABLE); rsPersonel = sqlPersonel.executeQuery("SELECT * FROM Personel"); } catch(Exception ex) { System.out.println(ex.getMessage()); }

302

} Burada yaplan ilemler yleydi. lk olarak Class snfnn forName metodu ile, alacak uygulama thread i iin bir JDBC Driver ykleniyordu. Ben Sql sunucuma Odbc kaynaklar zerinden balanmak istediim iin, JDBC nin ODBC ile anlamasn salayacak bir driver a ihtiyacm vard. te bu amala JdbcOdbcDriver n kullandm. Artk, uygulama altnda ve Doldur balkl butona basldnda, ilk olarak bu uygulama iin sisteme bir JdbcOdbcDriver yklenecekti. Bylece, alan uygulama iinden bu Driver kullanarak ODBC kaynaklarna eriebilecektim. Bu eriimi salamak iin ise tabiki geerli bir balantya sahip olmam gerekiyordu. Bunu ise, java.sql paketinde yer alan Connection snf sayesinde gerekletirebilirdim. java.sql.Connection conPersonel = java.sql.DriverManager.getConnection( "jdbc:odbc:sqlBaglanti"); Bu satr sayesinde, sisteme yklediim JDBC driver n kullanan bir Connection bileeni elde etmi oluyordum. Bu Connection bileeni, ODBC kaynaklarnda tanmladm sqlBaglanti isimli System DSN ini kullanacakt. Sonraki satr ise olduka ilginti.

java.sql.Statement sqlPersonel = conPersonel.createStatement(java.sql.ResultSet.TYPE_SCROLL_SENSITIVE java.sql.ResultSet.CONCUR_UPDATABLE); Nitekim burada, Sql cmleciini altrabileceim Ado.Net teki SqlCommand tarz bir bileen tanmlanyordu. Bunun iin java.sql paketinden, Statement snf kullanlyordu. Statement bileenini olutururken iki parametre verdim. Bunlar ResultSet snfna ait deerlerdi. Amacm uygulama iinde, elde ettiim kayt kmesi zerinde ileri geri hareket edebilmek olduu iin, TYPE_SCROLL_SENSITIVE deerini kullandm. Ayrca bu deer, yaplan gncellemelerin veya deiikliklerin ResultSet zerinde hareket ettiimizde grnmesinide salamaktayd. CONCUR_UPDATABLE deeri ise, update ilemlerinin gerekletirilebileceini belirtmekteydi. Bu deeri tam olarak

303

anlam deilim aslnda. Sanyorum ilerleyen zamanlarda kendisini gsterecektir. Aslnda Statement bileenini parametresizde oluturabilirdim. Bu durumda, kayt kmesi varsaylan olarak ileri ynl okumaya izin veren bir yapda olacakt. Dolaysyla, geriye doru yaplacak navigasyon hareketlerine izin vermeyecekti. Bu varsaylan deerde, TYPE_FORWARD_ONLY olarak belirtilmekteydi. ResultSet in davran belirleyecek baka alan deerleride vard. u an iin bana gerekli olan navigasyona ve insert, update, delete gibi temel tablo ilemlerine izin veren bir ResultSet idi. ResultSet in elde edilmesi ise, tanmlanan Statement nesnesinin, executeQuery metodu sayesinde gerekletirilmekteydi. Bu metoda parametre olarak almasn istediim Sql cmleciini vermitim. Artk elimde Sql sunucusundaki Personel tablosunda yer alan verlileri uygulama ortamna tayan bir veri kmesi vard. imdi uygulamay test etme zaman gelmiti. Hemen derleme ilemini gerekletirdikten sonra uygulamay altrdm ve Baglan balkl butona bastm. Herhangibir exception kmadndan, veri kmesini elde ettiimi dnyordum. imdi ise asl nemli olan ilk satrn verilerini, Frame deki swing bileenlerine nasl dolduracamd. ResultSet nesnem zerinde ileri geri hareket edebilmekteydim. lk satra gitmek iin first, son satra gitmek iin last, nceki satr iin previous ve sonraki satr iin ise next metodlar vard. nce, veri kmesindeki alan deerlerini bileenlere yazacak ortak bir metod yazdm. void Goster() { try { this.lbID.setText(rsPersonel.getString("PersonelID")); this.tfAd.setText(rsPersonel.getString("PersonelAd")); this.tfSoyad.setText(rsPersonel.getString("PersonelSoyad")); this.tfUcret.setText(rsPersonel.getString("SaatUcreti")); this.tfSure.setText(rsPersonel.getString("CalismaSuresi"));
304

} catch(Exception ex) { } } Buradaki kod satrlarnda, ilgili bileenlere setText metodu ile alan deerlerini yklyordum. Bunun iinde, ResultSet snfnn getString metodu ile alan adn kullandm. Tabi almak istediim deer integer olsayd getInt metodunu veya tarih olsayd getDate metodunu vb. n kullanabilirdim. Bu ilemlerin ardndan, Doldur balkl butona ait kod satrlarn ve dier navigasyon butonlarna ait olay kodlarn aadaki gibi dzenledim. public java.sql.ResultSet rsPersonel; public java.sql.Connection conPersonel;

void btnDoldur_actionPerformed(ActionEvent e) { try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); java.sql.Connection conPersonel = java.sql.DriverManager.getConnec "jdbc:odbc:sqlBaglanti"); java.sql.Statement sqlPersonel = conPersonel.createStatement(java.sql.ResultSet.TYPE_SCROLL_SENSITIVE rsPersonel = sqlPersonel.executeQuery("SELECT * FROM Personel"); rsPersonel.first(); Goster(); } catch(Exception ex) { System.out.println(ex.getMessage()); } } void btnIlk_actionPerformed(ActionEvent e) { try

305

rsPersonel.first(); Goster();

} catch(Exception ex) { } } void btnOnceki_actionPerformed(ActionEvent e) { try { rsPersonel.previous(); Goster(); } catch(Exception ex) { } } void btnSonraki_actionPerformed(ActionEvent e) { try { rsPersonel.next(); Goster(); } catch(Exception ex) { } } void btnSon_actionPerformed(ActionEvent e) { try { rsPersonel.last(); Goster(); } catch(Exception ex) { }

306

} void this_windowClosing(WindowEvent e) { if(rsPersonel!=null) { try { rsPersonel.close(); conPersonel.close(); } catch(Exception hata) { } } } Uygulamam altrdmda herey istediim gibiydi. Satrlar arasnda gezebiliyordum.

imd ise istediim, verileri gncelleyebilmek ve yeni satr veriler girebilmekti. Kaynaklarm aratrdmda, ResultSet snfnn bu ilemler iin kulland metodlar olduunu farkettim. Bu konular ksa bir sr inceledikten sonra Framee gncelleme ve ekleme ilemleri iin iki button kontrol ekledim ve aadaki olay kodlarn oluturdum.

307

void btngGuncelle_actionPerformed(ActionEvent e) { try { rsPersonel.updateString("PersonelSoyad",tfSoyad.getText().toString()); rsPersonel.updateString("PersonelAd",tfAd.getText().toString()); java.math.BigDecimal ucret=new java.math.BigDecimal(tfUcret.getText().toString()); rsPersonel.updateBigDecimal("SaatUcreti",ucret); java.math.BigDecimal sure=new java.math.BigDecimal(tfSure.getText().toString()); rsPersonel.updateBigDecimal("CalismaSuresi",sure); rsPersonel.updateRow(); } catch(Exception ex) { System.out.println(ex.getMessage()); } } void btnEkle_actionPerformed(ActionEvent e) { try { rsPersonel.moveToInsertRow(); rsPersonel.updateString("PersonelSoyad",tfSoyad.getText().toString()); rsPersonel.updateString("PersonelAd",tfAd.getText().toString()); java.math.BigDecimal ucret=new java.math.BigDecimal(tfUcret.getText().toString()); rsPersonel.updateBigDecimal("SaatUcreti",ucret); java.math.BigDecimal sure=new java.math.BigDecimal(tfSure.getText().toString()); rsPersonel.updateBigDecimal("CalismaSuresi",sure); rsPersonel.insertRow(); } catch(Exception ex) { System.out.println(ex.getMessage().toString()); } }

308

ResultSet bileenin iaret ettii veri kmesine yeni bir satr eklemek iin, nce moveToInsertRow metodu ile yeni bir satr alyor ve cursor bu satra konumlandrlyordu. Daha sonra ise, updateString ve updateBigDecimal metodlar ile, ilk parametre olarak verilen alanlara, ikinci parametredeki deerler yani textField bileenlerinin ierikleri atanyordu. Son olarak ise, insertRow metodu arlarak oluturulan yeni satr ResultSet e ekleniyordu. Gncelleme ilemindede teknik aynyd. Sadece insertRow yerine updateRow metodu kullanlmaktayd. Elbette buradaki gncelleme ilemleri iin, yine Statement nesnesi kullanlabilirdi. yleki; bu nesne ile sql cmlecikleri altrlabildiine gre insert ve update sql cmleciklerini altrarakta ekleme ve gncelleme ilemlerini yaptrabilirdim. JDBC ile ilgili konular gerekten saymak ile bitmiyor ve bitecek gibide deil. Bu konu ile ilgili olarak yeni bir 24 kahve molas yapsam az geleceine inanyorum. Ancak aratrmaya devam etmekte elbetteki byk fayda var. Yorucu bir hafta sonras JDBC ile ok fazla ey yapamasamda en azndan biraz kulak dolgunluu yakalam durumdaym. Ancak tabiki yeterli deil. Bakalm gelecek kahve molalarnda Java okyanusunun hangi derin sularnda, ne ykseklikteki alkantl dalgalarla bouuyor olacam.

Blm 21: Java, MySql Balants Java ile uralrda, MySql iin iine katlmaz m? Yeni nesil uygulamalarda uzun zamandr MySql kullanlmakta olan bir veritaban sistemi. ounlukla hzll ve performans ile dikkat ekiyor. Akas bugne kadar bu veritabann hi kullanmamtm. ounlukla Microsoft Sql Server veritaban sistemi olarak kullanmaktaym. Ancak internette olsun, yazl kaynaklarda olsun, Java programlama dilinin yannda mutlaka MySql e yer verilemekte. Bu belkide bir anlamda, pazar stratejilerinin bir sonucu olsa gerek. Nitekim mysql veritaban sistemini java platformunda kullanabilmek iin gerekli tm altyaplar kolayca salanm. Neyse, politik davalar ve pazarlama stratejilerini bir kenara brakp iimin bana dnsem

309

daha iyi olacak sanrm. Nede olsa bugne bugn uygulamacym. Bu hafta amacm, Java uygulamalarnda, MySql tablolarn kullanabilmekti. Tabi ncelikle bana neler gerektiini tespit etmem gerekiyordu. Elbette barol oyuncusu olan MySql veritaban sisteminin kurulmas ilk srada yer almaktayd. Dier taraftan, Java uygulamalarmda MySql tablolarna eriebilmemi salayacak bir veritaban src api sinede ihtiyacm vard. Nitekim, java mysql e nasl balanacan bilemezdi. Onun, veritabanlarna balanmak iin gsterdii arayzleri ve bu arayzlerdeki gerekli metodlar yeniden yazacak bir pakete ihtiyac vard. Bu dnceler eliinde hemen internette ksa bir aratrma yaptm ve http://dev.mysql.com/downloads/index.html adresine girdim. Bu adreste MySql ile ilgili aradm herey mevcuttu.

310

MySql iin 4.0 verisyonunu indirmeye baladm. Java platformumda gelitireceim uygulamalarn MySql tablolarn kullanabilmesini salayacak src api si ise, MySql Connector J 3.1 idi. Dier taraftan, amacm MySql zerinde sql cmlecikleri ile uramak olmad iin, Microsoft Sql Server daki Enterprise Manager a benzer bir arabirimede ihtiyacm vard. Aratrmamn cevab, MySql Control Center uygulamasyd. Elbette MySql i kurduktan sonra, sql ifadeleri ile tablolar oluturabilir, veritabanlarn ynetebilir ve daha pek ok ilemi gerekletirebilirdim. Ancak hedefim, bir uygulamac olarak u an iin tablo oluturmak gibi ilemlere minimum eforu

311

harcamakt. Asl ama, MySql tablolarn Java uygulamalarnda kullanabilmekti. MySql 4.0 yaklak olarak 22 megabyte lk boyutu ile sistemime indirdim ve kolayca kurdum. Makinemi yeniden balattmda, MySql iin gerekli windows servisinin otomatik olarak balatldn ve WinMySqlAdmin uygulamasnn Tray daki ikonunun yeil nn yandn grdm. Bu sistem bir yerlerden tandk geliyordu. Ba harfi Microsoft Sql Server Service Manager.

Srada ise, Java platformum ile MySql arasndaki iletiimi koordine edecek ve salayacak paketi yklemek vard. MySql Connector paketini sisteme kurduktan sonra hemen yardm dosyalarn stn kr kartrdm. Aslnda tam olarak ne aradm bende kestiremiyordum. Derken gzme CLASSPATH ile balayan bir paragraf takld. Bu paragrafta ksaca, java nn bu api yi kullanabilmesi iin bir takm ayarlarn yaplas gerektiinden bahsediliyordu. Yapmam gereken, ilgili jar paketinin bulunduu klasr CLASSPATH tanmlamasna eklemekti. Ben paketi D:\mysql-connector-java-3.1.3beta\mysql-connector-java-3.1.3-beta\ adresine yklediim iin classpath tanmlamasnda buna gre yapmam gerekiyordu. Yani sadece jar paketinin olduu klasr bilgisini Classpath tanmlamasna ekleyecektim.

312

Tabi Windows XP kullandm iin bu ayar, My Computer e sa tklayp Properties den Advanced ksmndaki Environment Variables blmnden yaptm. Bylece sistemde gelitirdiim tm java uygulamalar, MySql sunucusuna balanmak iin gerekli srcy ve bu srcnn salad yeleri kullanabilecekti. Sra gelmiti o heyecanl ana. Bakalm, bir java uygulamas iinden, MySql e balanabileceim driver ykleyebilecek miydim? WinMySqlAdmin alyordu. Motorlar hazrd. Geri sayma balamadan nce bir ka kk koduda yazmam gerekiyordu elbette. Yoksa roket kalkamadan patlayabilirdi. import java.sql.DriverManager; public class SurucuDogrula {

313

public static void main(String[] args) { try { Class.forName("com.mysql.jdbc.Driver").newInstance(); System.out.println("SURUCU YUKLENDI..."); } catch (Exception hata) { System.out.println("SURUCU YUKLENEMEDI..."+hata.getMessage()); } } } Uygulamay derleyip altrdm.

alyordu. Driver baarl bir ekilde o an alan proses iin yklenmiti. Artk daha hzl admlarla ilerleyebilirdim. Nede olsa iin en nemli ksm geride kalmt. Artk bana balanacam bir veritaban ve bu veritabannda yer alacak bir tablo gerekliydi. te tam bu srada aklma, indirdiim MySql Control Center program geldi. Bu program sisteme kurdum ve ta taaaaa. te aradm arabirim. Artk MySql zerinde kolayca tablo oluturabilir ve bu tabloya veriler ekleyebilirdim. MySql kurulduunda, balang olarak Test isimli bir veritabannda sisteme yklemiti. imdi bu veritaban zerinde bir tablo oluturacaktm. Personel isimli bir tablo oluturdum ve bir ka alan girdim.

314

Sonra ise, oluturduum tabloya bir ka satr veri girdim. Herey Enterprise Manager dan o kadar tandk geliyorduki bu ilemleri yapmam gerekten ok ksa srmt. Sonu olarak artk elimde Personel isimli bir MySql tablosu mevcuttu. stelik bir ka satr verisi bilem vard.

imdi Java y tekrardan devreye sokmann sras gelmiti. lk yapmak istediim tabiki MySql sunucusundaki test isimli veritanna balanmak ve Personel tablosundaki verileri ekrana

315

yazdrmakt. Bunu gerekletirebilmek amacyla uygulama kodlarm aadaki ekilde gelitirdim. import java.sql.*; public class SurucuDogrula { public static void main(String[] args) { try { Class.forName("com.mysql.jdbc.Driver").newInstance(); Connection conTest = DriverManager.getConnection("jdbc:mysql://localhost/test"); Statement komut= conTest.createStatement(); ResultSet rs = komut.executeQuery("SELECT * FROM Personel Order By ID"); while(rs.next()) { System.out.println("ID "+rs.getString("ID")); System.out.println("ISIM "+rs.getString("AD")); System.out.println("SOY ISIM "+rs.getString("SOYAD")); System.out.println("E POSTA "+rs.getString("EPOSTA")); System.out.println("--------------------------"); } conTest.close(); } catch (Exception hata) { System.out.println("SURUCU YUKLENEMEDI..."+hata.getMessage()); } } } Uygulama kodlarnda ncekilerden farkl pek bir ey yoktu aslnda. Hereyden nce en nemli fark, veritaban srcsnn MySql iin gelitirilmi olduu ve bu nedenlede, Connection
316

nesnesi oluturulurken buna uygun balant katarnn girildiiydi. Yerel sunucuda bulunan test isimli veritabanna bir balant amak istediimden, balant ifadesi jdbc:mysql://localhost/test eklinde olmalyd. Sonraki admlarda, sadece tablodaki verileri ekmek iin kullanacam sql sorgusunu altracak bir Statement nesnesi oluturmu ve sorgu sonularn bir ResultSet kmesine alarak, bu kmedeki satrlar while dngsnde gezmitim. Alan deerlerini getString("Alan ad") teknii ile alyordum. Elbetteki dngnn, veri kmesindeki tm satrlarda gezmesi iin next metodu kullanlyordu. Herey bittikten sonrada kaynaklar geri iade etmek amacylada, balant nesnesini kapatyordum. Srada satr ekleme, satr silme ve gncelleme gibi temel ilemler vard. Bu kez ResultSet e ait metodlar yerine sql cmleciklerini kullanmaya karar verdim. Statement snf bu ilemler iin, executeUpdate isimli bir metod sunuyordu. Bu metod ile, tablo zerinde yaplacak gncellemeler, satr ekleme ilemleri ve satr silme ilemleri gerekletirilebilmekteydi. Tabloya satr girilmesi ile ileme baladm. Bunun iin, try blou ierisine aadaki kod satrlarn ekledim. System.out.println("--------------------------"); int eklenen=komut.executeUpdate("INSERT INTO Personel (AD,SOYAD,EPOSTA) VALUES (Deneme,Deneme,Posta1@posta.com)"); System.out.println(eklenen+" SATIR EKLENDI..."); in tek esprisi, sql cmleciinin, Statement snfnn executeUpdate metodu ile altrlmasyd. Bu metodun geri dn deeri ise int tipindendi ve ilem sonucu etkilenen satr saysn vermekteydi. Uygulamay tekrardan derleyip altrdmda baarl bir ekilde satrn Personel tablosuna eklenmi olduunu grdm.

317

Srada gncelleme ilemi vard. Tek yapmam gereken sql cmleciini uygun ekilde deitirmekti. Burada, Personel tablosundaki tm satrlarn EPOSTA alanlarnn deerlerini deiitiriyordum. Komutun almas sonucu bu ilemden etkilenen satr says ise, executeUpdate metodunun sonucu olarak ortama aktarlmaktayd. System.out.println("--------------------------"); int eklenen=komut.executeUpdate("UPDATE Personel SET EPOSTA=admin@admin.com"); System.out.println(eklenen+" SATIR GUNCELLENDI..."); Silme ilemi de extra bir efor gerektirmemekteydi. Sql diline biraz olsun aina olduum iin kodda ne tr deiiklik yapmam gerektiini biliyordum. Burada rnek olarak ID alan 4 olan satr tablodan kartyordum. System.out.println("--------------------------"); int eklenen=komut.executeUpdate("DELETE From Personel WHERE ID=4"); System.out.println(eklenen+" SATIR SILINDI..."); Tm bu ilemler elbetteki MySql sunucusunda yer alan, Personel tablosunu dorudan etkilemekteydi. Artk MySql sunucusuna ait tablolarda kullanabilmekteydim. Veritabanlar ile ilgili konular tabikide ok geni ve kapsaml. Bu konu ile ilgili olarak yazlm binlerce sayfalk kitaplar olduunu, bu kitaplar grdm ve onlara korku dolu baklarla baktm sylemek isterim. Ancak temel olarak yapabileceklerimi bilmek bile son derece gzel. Hi olmassa imdilik bamn aresine bakabilirim. Bakalm kahve kokusunun zihnimde oluturduu grntler, beni baka hangi konulara srkleyecek.

Blm 22: Java ile Grafik izim Getiimiz hafta boyunca, Java dili ile fazla ilgilenemedim. Nitekim vaktimin byk ounluunu Whidbey i incelemekle geirmitim. Aslnda yazn bu scak dnemlerinde, beni yle
318

rahatalacak, fazla terleymeyecek almalar yapmak istiyordum. Whidbey beni bir nebze olsa rahatlatsada, klimann verdii ferahl salayamamt. Bana biraz elenceli ve elenceli olduu kadarda ie yarayacak bir konu gerekiyordu. Sonunda, Java programlama dili ile, grafiksel izimlerin nasl yapldn aratrmaya karar verdim. Zor olmayan, skc olmayan hatta zaman zaman ie yarar bir ekil oluturabilmek iin eski matematik bilgilerimi hatrlamama yol aan bu konu benim iin yeteri kadar elenceli ve gzeldi. Elbette, bir programlama dili ne kadar gl olursa olsun, salad grafiksel ktphanalerin kabiliyetleri, sradan bir tasarm programnn yerini tutamazd. Ancak insan durup dndnde, bu tip grafik programlarnn oluturulmasnda java, C# gibi dillerin kullanlabileceini kolaylkla anlayabilir. Sonu olarak, bir grafik programnda mouse ile, toolbar dan setiimiz bir ekli kolayca oluturabiliriz. Mouse ile srkleme bir olaydr. Seilen ekle gre ekranda bir vektr grafiin olumasda, dilin salad grafik ktphaneler ile mmkn olabilir. Olay dahada sofistike dndmde, C# ile veya Java ile yazlm, haritaclk, ehir planlama gibi programlarn olduunu da biliyordum. Hatta byle bir program i bandaykenden inceleme frsat bulmutum. Sonuta, elenceli olan grafik nesneleri aslnda byk apl projelerdede temel yap talar olarak rol alabilirlerdi. Kendimi bu dnceler eliinde gaza getirdikten sonra, yle az tadyla web sayfasna bir izik ataym dedim. Yapacam ilemler son derece kolayd. Bir applet tasarlayacak ve bu sayede bir web sayfasna, eitli grafik metodlar yardmyla vektr ekiller izebilecektim. Bunun iin aadaki gibi bir java kaynak kod dosyasn oluturdum. import java.awt.*; import java.applet.Applet; public class Grafikler extends Applet { public void paint(Graphics g) { g.setColor(Color.BLUE);
319

} }

g.drawLine(0,0,100,100);

Ekrana bir izgi izmek iin, Applet in paint metodunu kullandm. Burada, izgiyi Graphics snfnn, drawLine metodu ile oluturdum. Metod 4 parametre alyordu. lk ikisi x ve y koordinatlarn, son ikisi ise, izginin bittii yerin x ve y koordinatlarn vermekteydi. Ayrca, izgiyi mavi renkte boyamak istediimden, Graphics nesnesine setColor metodu ile Color numaralandrcsndan BLUE deerini atadm. Sonu aadaki gibiydi.

Elbette Graphics snfndan izebileceim ekiller sadece basit bir izgiden ibaret olamazd. Daha pek ok ekil vard. i dolu olanlar veya ii bo olanlar gibi. O halde yapmam gereken ortadayd. izebileceim her ekli deneyecektim ve sonularn grecektim. Bu ayn zamanda benim iin bir rehber olacakt. izim kodu ve altnda eklin grnts. Hemen parmaklar svadm ve klavyemin tularn andrmaya baladm. ncelikle temel ekillerle ie balama taraftarydm. Yani drtgenlerden. import java.awt.*; import java.applet.Applet; public class Grafikler extends Applet { public void paint(Graphics g) { g.setColor(Color.BLUE); g.setFont(new Font("Verdana",Font.BOLD,12)); g.drawString("ICI BOS DORTGEN",0,165);
320

} }

g.drawRect(10,10,100,140);

drawRect metodu 4 parametre almaktayd. lk ikisi, drtgenin yerletirilecei X ve Y koordinatlarn belirtirken, sonraki iki parametrede genilik ve ykseklii belirtmekteydi. Bir drtgenin iinin dolu olmasn veya kenarlarnn yuvarlatlm olmasn isteyebilirdik. Bunun iinde deiik metodlar vard. rnein fill ile balayan metodlar ii dolu ekiller olutururken, draw ile balayanlar ii bo ekiller oluturmaktayd. Hemen, dier olas drtgen ekillerinide izmeye altm ve aadaki rnek kodlar oluturdum. g.fillRect(10,10,100,140);

g.fillRoundRect(10,10,100,100,16,16);

321

g.drawRoundRect(10,10,100,100,64,128);

Round tipteki drtgenlerin kenarlar yuvarlatlrken son iki parametre kullanlmakta. Bunlardan ilki, yayn geniliinin piksel cinsinden deerini belirtirken ikinciside yayn yksekliini belirtiyor. Drtgenlerden sonra sra yaylara gelmiti. Lisans eitimim srasnda, yaylarla epeyce harneir olmutum. Ancak genelde yaylar elle katlara izmek yerine, yaylar ile ilgili teoremlerin ispatlarnn yaplmas ile uramtm. Srf bu nedenle, ilk ve orta okulda ok iyi olan resim izme kabiliyetimin yok olduunu syleyebilirim. Nitekim, artk ekil izmeye altmda o ekle matematiksel bir gzle bakyor ve olabilecek eitli ispatlar ve teoremleri hatrlyorum. Neyse, konuyu ve kafay fazla bulandrmadan yay izme ilemine girisek hi fena olmaz sanrm. g.drawArc(10,10,150,150,45,180);

322

g.fillArc(10,10,150,150,45,45);

Yaylarn izimindeki en nemli nokta son iki parametreydi. Bu parametrelerden ilki, balang asn derece cinsinden belirtirken, ikinci parametre yayn oluturaca ay derece cinsinden belirtmekteydi. Tabiki, ii dolu yay aslnda bir daire diliminden baka bir ey olmamaktayd. Ancak daireleri izmek iinde baka metodlar vard. Daireler oval ekillerin izildii fillOval yada drawOval metodlar ile elde edilebilirdi. Daire olmas iin, genilik ve ykseklik deerlerinin eit olmas yeterliydi. Bu ekilleride aadaki kod satrlar ile test ettim. g.setColor(Color.BLACK); g.setFont(new Font("Verdana",Font.BOLD,12)); g.drawString("YAYLAR...",0,165); g.fillOval(70,100,80,18); g.drawOval(30,30,75,75);

323

Srada daha komplike bir ekil olan poligonlar vard. Bir poligon izebilmek iin, drawPolygon yada fillPolygon metodlarndan birisini kullanabilirdim. Aralarndaki tek fark birisinin iinin dolu tekisinin ise bo oluuydu. Hangileri tahmin edin bakalm :) Elbette bir poligon oluturabilmek iin bir takm verilere ihtiyacm vard. Hereyden nce poligonlarn ke saylar belli deildi. Dolaysyla bu kelerin x ve y koordinatlarn belirleyecek iki integer diziye ihtiyacm olacakt. Bu dizilerden birisi, x koordinatlarn dieri ise y koordinatlarn tamalyd. te bu anda, kalem kada sarldm ve acaba bir kum saatinin sembolik resmini izebilir miyim diye dnmeye baladm. Oturup ciddi ciddi, kat zerinde, bir kum saatinin iki boyutlu grntsne ait ke koordinatlarn, ekrann ordinat sistemine gre karmaya altm. te kattaki almamm gzelim Fireworks grafik program ile ematize edilii.

324

Sonu olarak aadaki kodlar bana izleyen ekli verdi. Ehhh ite. Biraz da olsa kum saatini andryor. int xKoordinatlari[]={50,200,150,200,50,100}; int yKoordinatlari[]={50,50,150,250,250,150}; g.fillPolygon(xKoordinatlari,yKoordinatlari,6);

Artk tm ekilleri rendiime gre, bunlar harmanlayp beni daha ok neelendirecek bir uygulama yazabilirdim. rnein,

325

hepimizin kada izmekte hi zorlanmayaca, hatta patatesler ve bir ka kibrit p ile birlikte yapabilecei bir p adam, Java daki grafik metodlarn kullanarak izmek ne kadar zor olabilirdi ki? Doruyu sylemek gerekirse o basit p adam oluturabilmek iin bir sre almam gerekti. Kat zerinde matematiksel olarak koordinatlarn belirlenmesi, hangi eklin nereye gelecei derken saat sabahn oluvermiti bile. Ancak bir ka dakikalk bu eziyet sonrasnda aadaki program kodlar sayesinde olduka ilgin bir eser ortaya kartabilmitim. Belki Da Vinci kadar iyi deildi. Ancak yinede modern sanatn bir grntsyd. import java.awt.*; import java.applet.Applet; public class Grafikler extends Applet { public void paint(Graphics g) { g.setColor(Color.RED); g.setFont(new Font("Verdana",Font.BOLD,12)); g.drawArc(20,10,20,20,45,75); g.drawArc(50,10,20,20,45,75); g.setColor(Color.blue); g.drawLine(20,1,20,6); g.drawLine(25,1,25,7); g.drawLine(30,1,30,7); g.drawLine(35,1,35,8); g.drawLine(40,1,40,8); g.drawLine(45,1,45,9); g.drawLine(50,1,50,8); g.drawLine(55,1,55,8); g.drawLine(60,1,60,7); g.drawLine(65,1,65,7); g.drawLine(70,1,70,6); g.fillOval(25,18,9,9); g.fillOval(55,18,9,9);

326

g.setColor(Color.BLACK); g.drawArc(37,30,15,45,130,60); g.setColor(Color.orange); g.drawArc(10,20,50,50,-120,90); g.setColor(Color.black); g.fillOval(35,80,15,80); g.setColor(Color.MAGENTA); g.fillRoundRect(1,80,20,100,10,10); g.drawRoundRect(20,80,50,125,10,10); g.fillRoundRect(70,80,20,100,10,10); g.fillRoundRect(25,205,18,100,10,10); g.fillRoundRect(45,205,18,100,10,10);

} }

imdi gelde, u grafik programlarn, harita programlarn nasl yazyorlar dn. Dnmeden edemedim. Allah bu tip grafik tabanl yazlmlar Java veya C# gibi nesne ynelimli diller ile gelitirilenlere sabr versin. Bende bir ka have finacan ile ancak yukardaki kadar garip bir adam elde edebildim.

327

Blm 23: Servletler ile Dinamik Etkileimli Web Sayfalar Dnyorumda, internet yayld yaylal, dnyann ehresi deiti. Internet in ilk yllarnda, sadece belirli sayda sitede, basit html kodlar ile oluturulmu sayfalar yer alrd. rnein mezun olduum blme ait web sayfalarn o yllarda bir arkadam bitirme tezi olarak sunmutu. Sayfadaki tek atraksiyon, blmn retim grevlilerinin isimlerine tklandnda, onlar hakknda bir adet resim ve eitli bilgilerin bulunduu metinsel arlkl sayfalara giden linklerin yer almasyd. Ha birde mail gnderebileceimiz linkler vard. O tarihlerde bu sayfay arkadam notepad zerinde html taklar ile gerekletirmi ve tez ekibini olduka etkilemiti. Ancak ksa srede internet zerindeki web ierii inanlmaz lde ehre deitirdi. Bugn mteriye ynelik, irketlere ynelik ve daha pek ok alanda gelitirimi saysz internet sitesi var. Gelien teknolojiler ile birlikte bu sitelerin, kullanclar ile olan etkileimleride deiiklik gsterdi. yleki, artk dinamik etkileim sz konusu. Kullancnn taleplerini ileyen ve cevaplar reten, bu cevaplara gre sayfalarn dinamik olarak oluturulmasn salayan teknikler sz konusu. Aslnda ksa bir sre dnnce gelinen noktann gerekten gz kamatrc olduunu sylemek lazm. Nitekim her ne zaman Amazon dan bir kitap almak istesem, baktm rnn yannda mutlaka, "bu rn alanlar bunlarda ald" gibisinden ynlendirici ierikler grmekteyim. Hatta bazen kiiye zel indirimlerin yapldda oluyor. Bu dinamik etkileime verilebilecek basit ve nemli rneklerden birisi aslnda. nk, web sayfasnn grnm ve ierii benim vermi olduum taleplere gre, dinamik olarak deimekte. Benim iin sayfada grnen tavsiye rnler, baka bir kullanc iin baka rnler olabilir. Peki acaba, dinamik etkileimli web sayfalar nasl gelitirilebilir? lk olarak, dinamik etkileimi gerekleyebilecek en iyi art gl, esnek bir programlama dilinin olmasdr. Bugn itibariyle, ben bu tip ileri Asp.Net platformunda C# programlama dilini kullanarak gerekletirmekteyim. Acaba eskiden nasld?
328

Kaynaklarm aratrdmda, ilk olarak perl dilinin cgi ile yan yana anldn kefettim. Daha nce bu konular ile hi uramadmdan tam olarak nasl kullanldklarn bilmiyorum. Ancak dinamik etkileime izin veren bir yapy saladklarn anlayabiliyordum. Nitekim, cgi sonrasnda servlet, jsp, asp gibi modellerin kmas, cgi n bir takm snrlamalarnn olduunu gstermekte. Bunu kaynaklarmdan ksaca aratrdmda, cgi ile gelitirilen sunucu tarafl web sitelerinde, kme probleminin daha sk yaanmasna neden olabilecek bir tekniin kullanldn rendim. yleki, cgi ile gelitirilen bir web sitesinde, sunucu tarafl kodlama iin genellikle perl dili kullanlarak yazlan programlam mevcut. Sayfaya yaplan her bir kullanc talebi iin, bu programlar ayr birer sre oluturacak ekilde altrlyormu. Buda ayn anda siteye balanabilecek kullanc saysnda bir snrlama getiriyormu. Dolaysyla, hastaln tedavisi yine ve her zamanki gibi ilk olarak Sun firmasndan servlet ler ile gelmi. Bir servlet aslnda, java byte kodlarndan oluan bir snf nesnesinden baka bir ey deil. Sunucu tarafl olan bu nesneler, java dili ile yazlabildiinden, web sayfasna mthi bir programlama kabiliyeti getirmekte. Servlet lerin tek dezavantaj okuduum kadar ile, html ierii ile kodlarn ayr olarak yazlmasn gerektirmesi. Bu html ierii ile sunucu tarafl kodlarn ayn asp sayfalarnda olduu gibi bir arada kullanlabildii jsp lerin domasna yol am. Geri u anda, Asp.Net ile uygulama gelitiriren srekli olarak code-behind tekniini kullanmaktaym. Yani web sayfasna ait htm ierii ile, C# uygulama kodlarm tamamen farkl dosyalarda duruyor. Bu iimi dahada kolaylatryor. Ancak tabiki servlet ler Asp.Net ortamnda olduu gibi bir takm kolaylklar ve gler kazandramam zamannda. Tabi bu noktada aklma gelen soru jsp lerin servlet lere kar bir stnlkleri olup olmad. Gerek u ki, ikisi arasndaki tek fark kodlamalarn yazl yerleri. Edindiim bu ksa bilgilerin ardndan hemen servlet lerin nasl uygulandn denemeye karar veriyorum. Lakin, bana gereken bir takm materyaller var. ncelikle, Asp.Net ile gelitirdiim web sayfalarndan biliyorum ki bana sanal bir web sunucusu lazm. te bu noktada devreye adn ska duyduum, Apache
329

Tomcat sunucular giriyor. Lakin daha basit ve iin uzmanndan bir zm var. JSWDK. Jswdk, aslnda java servletlerini ve jsp sayfalarn barndrp altrabilen bir web sunucusu. Gelitiricisi ise tabiki Sun. Bu nedenle ilk olarak sistemime, JSWDK y kurmam gerekiyor. Bu amala, Sun n internet sitesinden, http://java.sun.com/products/servlet/archive.html linkinden (bu gn itibariyle) JSWDK nn 1.0.1 versiyonunu indirdim.

Yaklak olarak 745 kb lk dosyann windows versiyonunu bilgisayarma indirdikten sonra, tek yapmam gereken zip dosyasn D srcmn altna amak oldu.

330

Artk servlet leri altrabileceim java web sunucum hazrd. Lakin yapmam gereken bir takm ayarlar olduunu rendim. Bunlardan ilki CLASSPATH ayarlamasyd. CLASSPATH e henz neden eklendiini anlmayamadm bir jar paketinin yolunu bildirmem gerekiyordu. Bu, Java gelitirme kitinin kurulduu dizindeki, lib klasr iindeki tools.jar paketi idi.

Java web sunucusunun, barndrd servletler ve web sayfalarn ileyebilmesi iin ncelikle altrlmas gerektiini, IIS (Internet Informatin Server) daki deneyimlerimden biliyordum. Sisteme kurduum java web sunucusunu altrabilmek JSWDK nn kurulduu klasrdeki ServersStart.bat isimli dosyay altrmam yeterli olacakt. Bu amala bu batch dosyasn altrdm. Bu ilemin ardndan, komut satrnda aadaki ekran grntsn elde ettim. Sanyorumki web sunucusu almaya balamt.

331

Ancak elbetteki sunucunun alp almadndan bu ekilde emin olmak istemiyordum. Nitekim IIS sistemde alrken localhost u tarayc penceresinden talep ettiinde sistemin altna ilikin bir asp sayfas elde ediyordum. Biliyordumki benzer bir strateji java web sunucusu iinde uygulanmalyd. Bu nedenle kaynaklarm aratrmaya baladm ve tarayc penceresinde, http://localhost:8080/ adresini girdim. Aynen komut satrnda bana sylendii gibi. Sonu tam istediim gibiydi.

332

Artk java web sunucusunun altn biliyordum. Peki bunu nasl durduracaktm. StartServer.bat dosyasnn almas sonucu alan komut penceresini kapattm. Daha sonra ise, tarayc penceresini kapatp tekrar atm ve http://localhost:8080/ sayfasn yeniden ardm. Ancak sayfa taraycya gelmedi. Yani sunucu almas durmutu. Bununla birlikte ayn ilemi StopServer.bat dosyasn altrarakta gerekletirebilirdim. Artk, alan bir java web sunucum olduuna gre basit bir servlet uygulamas yazabilirdim. Servlet ler teknik olarak, java byte-code dosyalarndan ibaretti.
333

Bu dosyalar, java web sunucusu altrldnda devreye giren JVM tarafndan, snf olarak derleniyor ve taleplerin ilenmesi iin kullanlan dinamik nesnelere dnyordu. Aslnda big picture n servlet tarafndaki izah aadaki ekil ile basitde olsa ifade edilebilirdi.

lk olarak, Frontpage ile aadaki HTML kodlarndan oluan basit bir form sayfas yaptm. Amacm, kullancnn bu sayfada girdii verileri, bir servlet ile almak, ilemek ve bir sonu sayfas reterek kullancyla gndermek. <html> <head> <title>Alan Hesaplar</title> <meta http-equiv="Content-Type" content="text/html; charset=windows-1254"> <meta http-equiv="Content-Language" content="tr"> </head> <body> <form action="http://localhost:8080/servlets/AlanHesap" method="get"> <table border="1" cellpadding="5" cellspacing="0" width="17%" bordercolor="#800000" bgcolor="#FFCC66" id="table1"> <tr>
334

<td width="28"><font size="2"><b>En</b></font></td> <td width="44%"><input type="text" name="EN" size="11"></td> </tr> <tr> <td width="28"><font size="2"><b>Boy</b></font></td> <td width="44%"><input type="text" name="BOY" size="11"></td> </tr> <tr> <td colspan="2"> <input type="submit" value="Alan Hesapla" name="B1" style="float: right"></td> </tr> </table> </form> </body> </html>

Oluturduum bu basit AlanHesaplar.html isimli sayfay, java web sunucusunda altrabilmek iin, D:\jswdk1.0.1\webpages klasr altna kaydettim. Bu html sayfasndaki belkide en nemli nokta, Form daki submit butonuna baslmas halinde, form bilgilerinin hangi adreste ileneceidir. Bunun iin, <form method="get" action="http://localhost:8080/servlets/AlanHesap"> satrn kullandm. Burada aka grld gibi, java web sunucusu zerindeki AlanHesap isimli bir servlet, bu formdaki verileri ileyecekti. Servlet ler, java web sunucusunda genellikle, D:\jswdk-1.0.1\webpages\WEB-INF\servlets
335

adresinde tutulmaktayd. Bende bu kural deitirmedim. imdi, web sayfamdaki ierii ileyecek ve talepleri karlayacak, AlanHesap isimli servlet ime ait java byte-code dosyasn oluturmam gerekiyordu. Bunun iin, yine notepad editr ile, D:\jswdk-1.0.1\webpages\WEB-INF\servlets klasr altnda, aadaki kodlara sahip AlanHesap.java dosyasn oluturdum. import import import import java.io.*; javax.servlet.*; javax.servlet.http.*; java.*;

public class AlanHesap extends HttpServlet { public void doGet(HttpServletRequest talep, HttpServletResponse cevap) throws IOException, ServletException { cevap.setContentType("text/html"); PrintWriter cikti=cevap.getWriter(); String en=talep.getParameter("EN"); String boy=talep.getParameter("BOY"); double eni=java.lang.Double.parseDouble(en); double boyu=java.lang.Double.parseDouble(boy); double alan=eni * boyu; cikti.println("<b>"+en+" x "+boy+" = "+alan+"</b>"); } } Hemen kod satrndan derleme ilemine getim. Ancak oda ne? 6 tane hata mesaj aldm. Tam anlamyla yklmtm.

336

Ancak hata koldarna baktmda ve javax.servlet isimli paketin bulunamadn anladmda, ne yapmam gerektiini biliyordum. Hemen, servlet isimli bir paket aramaya baladm. Neyseki, D:\jswdk-1.0.1\lib klasrnde bir tane vard. Bu paket iinde, kodlarda kullandm HttpServletResponse, HttpServletRequest, HttpServlet gibi snflar yer almaktayd.

337

Hemen bu paketi CLASSPATH tanmlamalarmn sonuna aadaki gibi ekledim.

Byte-Code dosyasn yeniden derlediimde hatasz bir ekilde derleme ileminin gerekletirildiini grdm. Sayfam altrmak ve servlet in ileyip ilemediini grmek iin sabrszlanyordum. Lakin ncesinde neler yaptm anlamam gerektiine karar verdim ve kod satrlarn incelemeye baladm. Hereyden nce yazdm uygulama bir servlet olaca iin, HttpServlet snfndan tretilmiti. doGet metodunun ismi rastgele verilmi bir isim deildi. Form zerindeki bilgileri servlet e geirirken metod olarak get tekniini kullanacam belirtmitim. Bu nedenle get teknii ile alacak form sayfalar iin doGet metodu kullanlyordu. Eer form zerindeki bilgileri post tekniine gre gndermek isteseydim bu durumda doPost metod ismini kullanmam gerekecekti. Elbette form zerindeki method taksnda post olarak ayarlamam gerekirdi. doGet metodu iinde iki nemli parametre yer almaktayd. public void doGet(HttpServletRequest talep, HttpServletResponse cevap) throws IOException, ServletException HttpServletRequest parametresi ile, kullanclarn taraycalarndan gelen talepleri alabiliyordum. HttpServletResponse ilede, tarayclara cevap gnderebiliyordum. HttpServletRequest nesnesinin getParameter metodu ile, form zerindeki EN ve BOY metin kutularna ait deerleri alabilmekteydim. String en=talep.getParameter("EN"); String boy=talep.getParameter("BOY");

338

kt retmek iin, IO paketinde yer alan, PrintWriter snfn kullanyordum. Bu snfa ait nesneyi olutururken, HttpServletResponse nesnesinin getWriter metodunu kullanmaktaydm. PrintWriter cikti=cevap.getWriter(); Bylece, PrintWriter nesnesinin rnein println metodu ile, talepte bulunan taraycya bir eyler yazdrabilirdim. cikti.println("<b>"+en+" x "+boy+" = "+alan+"</b>"); Az ok, servlet ler ile dinamik kodlamann nasl gerekletirilebileceini anlamtm. Elbetteki, servlet ler ile ilgili konularn daha derin olduunu ve renmem gereken daha pek ok ey olduunu biliyordum. Bu dnceler ierisindeyken, sayfam test etmeye baladm. Sonuta pek bir ie yaramayan bir alma olaca kesindi. Ancak en azndan bir taraycdaki kullanc hareketlerini, sunucu tarafl kodlama teknii ile nasl ele alabileceimi kefetmitim. Hemen sayfam denemeye karar verdim ve tarayc pencereme aadaki linki girdim. http://localhost:8080/AlanHesaplar.htm tabiki sayfa almad. nk, java web sunucusunu henz altrmamtm. Hemen, StartServer.bat dosyas ile sunucuyu altrdm ve tekrar sayfam ykledim. Bu kez sayfam almt.

339

Evet, imdi forma bir eyler yazp servlet imin almasn seyredebilirdim. te sonu. Gmmmmmmm...

Ne olmutuda, servlet bulunamam ve altrlmamt. Hereyi tekrar tekrar gzden geirdim. Kodlarda bir hata yoktu. Aksi halde uygulama derlenmezdi. Sonra servlet dosyalarn yanl bir klasre koymu olabileceimi dndm. Ancak bu da deildi. Bu arada kendime bir kahve daha yaptm ve evin bir ucundan dierine yrmeye baladm. Bir yudum alyor kendi kendime "alla allaaa" diyordum. Sonra tabiki dayanamayp kaynaklarma bakmaya karar verdim. Meerse sorun s harfindeymi. Eer bu proje bir uzay program olsayd sanrm mekik bu s harfi yznden oktan aya arpm olurdu. Adres satrndaki,

340

http://localhost:8080/servlets/AlanHesap?EN=Java24&BOY=Java24&B1=G ifadesini,

http://localhost:8080/servlet/alanHesap?EN=Java24&BOY=Java24&B1=Gi satr ile deitirdiimde sorun zlmt. Aradaki fark gerektende tek bir s harfiydi. Servlet imi servlets isimli klasr altna atmtm. Ancak sanal suncuda yazlan adreste servlets yerine servlet kullanmam gerekiyordu. Hemen giris.htm sayfasndaki kodu dzelttim. Bu kez baarmtm. Servlet alm, form zerindeki bilgiler ilenmi ve sonu retilmiti.

Artk servlet leri az okda olsa anlamtm. Sonuta, web sayfalarnn sunucu tarafl ksmlarnda dinamik etkileime izin veren kodlamalar java dili ile gerekletirildiinden bundan sonra iim daha da kolayd. Lakin kahvemin son yudumlarn ierken, JSP olaynn ne olduunu dnmeye baladm. Sanrm nmzdeki hafta JSP olayna gireceim.

Blm 24: lk Bakta JSP (Java Server Pages) Bu hafta, JSP ile dinamik etkileimli bir web sayfas oluturmak iin kendimi baya bir hrpaladm. Sorunlar, JSP olarak yazdm rnek sayfalar, servlet leri altrmak iin kullandm JSWDK kitinde ba gsterdi. Nedense hi bir JSP
341

sayfasn altramadm. Evin iinde bir o keye bir bu keye koutururken nerde hata yaptm bulmaya alyordum. Sorun byk bir ihtimalle benim sistemimden kaynaklanyordu. Tabiki benimde yaptm yanl ayarlamalar olabilirdi. Sonuda kurcalaya kurcalaya gzelim JSWDK kitinide bozuvermitim. Ne yapabilirim diye dnrken, aklma parlak bir fikir geldi. Elimdeki kaynaklar JSP uygulamalarna ufak bir dokunu yapmt. Ancak bu konuda esasl bir kaynam olmas gerektii inancndaydm. Her ne kadar amacm mimarinin temellerini ve alma sistemini anlayp ok basit bir uygulama gelitirmek olsada, yinede elimin altnda her zaman bavurabileceim bir kaynak olmas gerektiini dnyordum. Bu dnceler ile hemen yola koyuldum ve Kadky deki kitaplar gezmeye baladm. Sonunda aradm kitab bulmutum. Pusula yaynlarndan Numan Pekgz n JSP isimli kitab.

in gzel yan, kitapta JSP sayfalarn kurup altrabileceim uygulamalarn yer ald bir CD de mevcuttu. Byk bir heyecan ile kiab aldm ve yol boyunca otobste okuyarak geldim. Eve geldiimde, JSP sayfalarn altrabileceim JRun sunucusunun nasl kurulacan ve kullanlacan oktan renmitim bile. Hemen kitapta bahsedilen admlar, birer birer ilemeye baladm. JRun, u anda Macromedia firmasna ait olan bir rn olmakla birlikte kitabn bu srmnde bir nceki verisyonuna yer verilmi. Ama hi nemli deil. Sonuta JSP sayfalar alyor. Kurulumu bitirdiimde, D:\Program Files\Allaire\JRun\ dizinine, java web sunucum kurulmu, hazr ve nazrd. Artk gelitirmek istediim JSP sayfalarn D:\Program Files\Allaire\JRun\servers\default\default-app\

342

klasr altna atacaktm. Tabi kurulum basit olmasna ramen yinede sistemde yaplmas gereken ince ayarlamalarda vard. Bunlarda birisi her zamanki gibi mehur ClassPath tanmlamalar ile ilgiliydi. JSP sayfalarnn baarl bir ekilde ilenebilmesini salamak iin, D:\Program Files\Allaire\JRun\lib\ext\servlet.jar adresindeki servlet.jar paketinin Classpath tanmna eklenmesi gerekiyordu. Bu ilemin ardndan hemen ilk olarak aadaki gibi basit bir sayfa oluturdum ve bu sayfay jsp uzants ile, D:\Program Files\Allaire\JRun\servers\default\default-app klasr altna kaydettim. <html> <head> <title>ilk jsp</title> <body> <% String adim="Burak"; out.println(adim); %> </body> </html>

imdi tek yapmam gereken, tarayc penceresinde, http://localhost:8100/ilk.jsp adres satrn girmekti. Bende yle yaptm.

aka maka, ilk JSP sayfam yazmtm. Evet herey iyidi hotu ama, bu JSP nedemekti? Ne ie yaryordu? Hereyden nemlisi
343

alma sistemi neydi? JSP ile ilgili tm kaynaklarmdaki bilgilerimi yle bir gzden geirdim ve byk resme(big picture) ulamak iin admlarm atmaya baladm. Hereyden nce, geen hafta servlet ler yardmyla, kullanc ile dinamik etkileimli web sayfalarnn nasl gerekletirilebileceini incelemitim. JSP (Java Server Pages) lerde ayn ii yapmaktayd. Aralarndaki farkllklar dndmde ilk akla gelen, JSPlerde html ierik ile Java dilinin kullanld sunucu tarafl (server-side) kodlarn bir arada bulunmasyd. yleki servletler ile alrken, java kodlarn kullanarak html ktlarn retmek gerekten zahmetli bir iti. Akas hammallkt. Oysaki JSPde html ierik ile java kodlar ayn sayfada yer alabilmekteydi. Bu ise, tasarmn etkili olduu, sunucu tarafl java kodlar barndran web sayfalarnn kolayca oluturulabilmesi demekti. Bu fark nemsiz gibi grnsede, gelitirme zamannda olduka byk tasarruf salamakta. Yaklak olarak 8 saatlik bir JSP ci olarak bunu ben bile syleyebiliyorum. Dier yandan bence asl nemli olan fark, JSP sayfalarnn ileyi ekli. yleki, olduka ilgin bir durum sz konusu. O da, JSP lerin, istemciler tarafndan talep edildiklerinde, eer bu talep ilk kez gereklemise, java kodlarnn, servletler haline getirilmesi ve snf olarak derlenmesi. Yani, eninde sonunda yazlan JSP ler derlencekleri zaman iin iine servlet ler girmekte. Ksacas JSPler bizi servlet yazma derdinden kurtaryor diyebiliriz. Ancak tabiki Jsp lerin servlet ler ile tmleik olarak almasda sz konusu. Aslnda Java sunucu sayfalarnn alma prensibini aadaki ekil ile daha iyi anlatabileceime inanyorum.

344

Jsp sayfalarnn alma prensibi bu ekilde. Yani, kullanc bir JSP sayfasn ilk kez talep ettiinde, sunucu bu talep zerine ilgili JSP sayfasnn java kodlarndan bir servlet oluturuyor. Bu servlet dosyas aslnda bir java byte-code dosyas. Sonraki admda ise byte-code dosyas class olarak derleniyor. Derlenen class, kullancdan gelen parametreler vs... varsa bunlarla birlikte altrlyor ve retilen sonular html olarak tekrardan java sunucusuna gnderiliyor. Java sunucusu ise, bu html sonularn kullancnn taraycsna gnderiyor. Bu sistem, sadece oluturulan Jsp sayfas kullanc tarafndan ilk kez talep edildiinde gerekletiriliyor. Nitekim bundan sonraki arlarda zaten var olan derlenmi class dosylar alyor. Elbette biz Jsp sayfamz deitirirsek buradaki sre tekrarlanacaktr. Peki bu teori gerekten bylemi? Bunu bir ekilde ispat etmem gerektiini dndm kendimce. Gelitirdiim, ilk.jsp dosyasnn aynsnn farkl isimli bir verisyonunu oluturdum. Yeni.jsp olarak. Daha sonra bu sayfay taraycdan talep ettim. Sonra, alt klasrleri gezinmeye baladm. Nemi aryordum? inde Yeni kelimesi olan java ve class uzantl dosyalar. Eer bu dosyalar bulursam gerektende teorinin almasn ispatlam olucaktm. Derken, D:\Program Files\Allaire\JRun\servers\default\defaultapp\WEB-INF\jsp

345

klasrnde, bu dosyalar buldum.

Ancak bu ispatta eksik olan bir eyler var gibiydi. Belkide ben Jsp dosyasn kaydettiimde, bu dosyalar otomatik olarak oluturulmutu. te bu hipotezi ykmann tek bir yolu vard. Yeni bir jsp dosyas oluturacak, bu sayfann oluturulu zamann kaydedecek sonra bir kahve molas verecektim. Geldiimde taraycdan bu sayfay altracak ve oluan java ve class dosyalarnn sresini, jsp dosyasnn oluuturulu sresi ile karlatracaktm. Bunun zerine, Yeni.Jsp den bir kopya daha oluturdum. YeniGibi.jsp.

imdi de kahve molasna kma zaman. Neyse, kahve molasna kp geldim. Bir ka dakika sonra geldiimde hemen, jsp klasrnn iine baktm.

346

Grnrde YeniGibi.jsp iin oluturulmu java ve class dosyalarndan eser yoktu. Derken taraycda bu sayfay tekrardan altrdm ve jsp klasrne tekrar baktm.

Artk ispat gereklemiti. Jsp ler ile ilgili enmli bir nokta, html sayfalar ile iie yazlabilmeleriydi. Ayn asp sayfalarnda olduu gibi. Tabi java ile yazlan bu sunucu tarafl kodlar, tam anlamyla nesne ynelimli bir dilin avantajlarn kullandndan olduka esnek ve gl sonular elde etmemizi salamaktayd. Peki iie alan bu sayfalarn ileyiine yakndan bakmak isteseydim nasl bir ekli kafamda canlandrabilirdim diye dnmeye baladm. Sonuta aadaki nacizane ema ortaya kt.

347

Bu ema aslnda, Jsp nin bir avantajnda gstermekte. O da, tasarm ve kodlama katmanlarnn ayr ayr ele alnmas. Yani, bir tasarmc ve bir java programcs kafa kafaya verdiklerinde, dnyann en ok konuulan etkileimli web sayfalarn yazabilirler. Kodlamac java dili ile sayfay kodlarken, tasarmc sadece grsel tasarm ile ilgilenecektir. Geri ben, Asp.Net ile gelen code-behind modelini bu modele tercih ederim. Nitekim oradada kod katman ve tasarm katman ayrdr. Hatta o kadar ayr olabilirlerki, code-behind teknii sayesinde, aspx sayfalarna ati kodlar C# gibi nesne ynelimli bir dil ile ayr snf dosyalarnda toparlanabilir. Tabiki .net iindeki bu teknik servletlere nazaran, kod ve sunum katmannn daha iyi entegre almasn salayan bir yap zerinde tekil edilmi. Bu kadar laf kalabalndan sonra aslnda ie yarar bir rnek yapmann zaman geldi. e yarar dediysem ufkumu amak iin teebbste bulunacak ie yaramaz bir uygulamdan bahsediyorum elbette. En azndan, bir jsp sayfasndaki form bilgilerinin baka bir jsp sayfas tarafndan ele alnmasn
348

salamak gibi basit bir ilem gerekletirebilirim. Bu amala aadaki kodlar ieren jsp sayfalarn oluturdum. Giris.jsp sayfas; <html> <head> <title>ilk jsp</title> <body> <form name="form1" method="post" action="kontrol.jsp"> <table width="200" border="0"> <tr> <td>Ad</td> <td><input type="text" name="tAd"></td> </tr> <tr> <td>Soyad</td> <td><input type="text" name="tSoyad"></td> </tr> <tr> <td></td> <td><input type="submit" name="Submit" value="Submit"></td> </tr> </table> </form> </body> </html>

kontrol.jsp <html> <head>


349

<title>Giri</title> <meta http-equiv="Content-Type" content="text/html; charset=iso8859-1"> </head> <body> <table width="200" border="0"> <tr> <td><strong><%=request.getParameter("tAd")%></strong></td> </tr> <tr> <td><strong><%=request.getParameter("tSoyad")%></strong></td> </tr> </table> </body> </html> Yazdm kodlarda tek gze arpan nokta, form daki field lara ait deerleri, kontrol.jsp dosyasnda, request snfnn getParameter metodu ile alyor oluumdu. Hemen, giri.jsp sayfasn sunucuda altrdm ve bilgileri girip buton kontrolne bastm. Sonuta, kontrol.jsp sayfam alt ve aadaki ekran grntsn elde ettim.

Jsp olduka geni bir konu ve incelenmeye deer. u an iin alma prensibini, en byk avantajn ve nasl gelitirildiini biliyorum. Ancak elbetteki bir ka gnlk alma ile Jsp ye hakim olamam. Hi olmassa ilk bakta gze arpan noktalar irdelemi oldum. Bu kahve molamz ile birlikte Java ile 24 Kahve Molasnn da sonuna gelmi bulunuyoruz. Ancak bunun bir son olmadn hatta bir balang olduunu sylemek isterim. Nitekim
350

deinemediim pek ok konu var. rnein deerli bir okurumuzun belirttii gibi a programcl. Bunun dnda, thread ler, koleksiyonlar (torbalar), IO (Input-Output) ilemleri vb... Dolaysyla bu konularada deinmek ve incelemek dncesindeyim. Bundan sonrasnda, her cuma olmasa bile dzenli olarak bahsettiim konular inceleyecek ve yazmaya alacam. Umuyorum ki bu yaz dizisinde sizlere Java dilini bir nebze olsun retebilmiimdir. Ben bir eyler rendim. Ama elbetteki reniklerimi tekrar etmessem, gerek projelerde kullanmassam kolayca unutabilirim. Sizlere de tavsiyem bol bol tekrar etmeniz ve projeler gelitirmeniz olacaktr. Hepinize mutlu ve salkl gnler dilerim. Salcakla kaln.

Kaynak: http://www.bsenyurt.com/

351

You might also like