Java ile Programlama

gölge_adam

Katılımcı Üye
20 Şub 2007
517
8
TeXaS
Java ile Programlama (24 Bölümlük Ders)




[FONT=Verdana, Arial, Helvetica, sans-serif]Java daha önceden bahsettiğim gibi, 90lı yıllarda doğmuş bir dil idi. Üretici firma Sun. Java ile yazılan programların ilk ve en ayır edici özellikleri, platform bağımsız olmaları. Bunu nasıl sağladıklarını araştırdığımda, Virtual Java Machine ( Sanal Java Makinesi) kavramı ile karşılaştım. Bu aslında günümüz işletim sistemlerinin tümünde bulunuyor. Hatta kullanıdığımız web tarayıcılarının sistemimizde olması bile yeterli. Bu noktada kafam karışmıştı. Bu ara programın amacı neydi acaba? Çok geçmeden cevabı buldum. Biz java dili ile bir program yazdığımızda bunu Java Derleycisi ile derliyoruz. Derlenmiş olan bu dosyalar bytecode adı verilen bir hale geliyor. JVM ise, derlenmiş bir java uygulaması başlatıldığında, bu uygulamayı sisteme uygun bir halde yorumluyor ve çalıştırıyor. Dolayısıyla JVM ara programının yüklü olduğu her sistemde bu kodları değiştirmeden çalıştırabilme imkanına sahibiz. Sanıyorumki bugünlerde mobil telefonlarda java ile yazılmış oyunların çokluğunun sebebi bu olsa gerek. İlk öğrendiğim bu kavram aslında bu programlama dilinin gücünü ve her programcının az da olsa gilmesi gerektiğini gösterdi bana. O halde koşmak lazım. Hedefimiz büyük.[/FONT]
[FONT=Verdana, Arial, Helvetica, sans-serif]Elbette kuru kuruya bunları yazmak kolay. Ama basit bir uygulamada geliştirmek ve bir yerden başlamak gerekli. Öncelikle benim Java programlarını yazmam için gereken bir takım şeyler var bundan eminim. Çünkü bu her zaman böyle olmuştur. İhtiyacım olan ilk ve hatta tek şeyin, JSDK (Java Software Developer Kit-Java Yazılım Geliştirme Kiti) olduğunu öğreniyorum. Bunu kitaplar ile birlikte gelen cd�lerden temin edebiliriz. Ama bence en güncel olan sürümü takip etmek ve kullanmak her zaman daha iyidir. Küçük bir araştırma sonucu aşağıdaki adrese giriyor ve JSDK�ların yayınlanmış tüm sürümlerine ulaşıyorum. [/FONT]
[FONT=Verdana, Arial, Helvetica, sans-serif]http://java.com/en/download/manual.jsp[/FONT]
[FONT=Verdana, Arial, Helvetica, sans-serif]
j24_1_5.gif
[/FONT]

[FONT=Verdana, Arial, Helvetica, sans-serif]Ben burada Offline Kurulum seçeneğini seçtim. J2SE için yaklaşık olarak 15 megabyte�lık bir dosya indirdi. Artık indirilen bu dosyayı sistemime kurabilirim. Kurulum adımları son derece kolay. Yazılım kitinin kurulması ile birlikte artık sistemim, java uygulamalarını geliştirmem için uygun bir yapıya sahip oldu. Evet her şey şu ana kadar iyi gitti diyebilirim. Peki ama javayı nerde hangi editorde yazabilirim. Araştırmam sonucunda her zaman olduğu gibi en güçlü en yetenekli en karizmatik editor ile bu işleri halledebileceğim sonucuna vardım. NOTEPAD. Tek yapmam gereken, uygulamayı notepad ile yazıp, java uzantısı ile kaydetmek. Daha sonra yazılan bu uygulamlayı bytecode�lara çevirmek için, javac (Java Compiler-Java Derleyicisi) programını kullanmak. Sonra ise, yazılımış olan uygulamayı başlatmak için java programı ile yazılan bytecode�ları çalıştırmak. [/FONT]
[FONT=Verdana, Arial, Helvetica, sans-serif]Aslında ilk uygulamamı yazmak için sabırsızlanıyorum. Kaynakların hemen hemen hepsi, yeni bir programlama dilini anlatırken ilk yazılan programı, Hello World yada Merhaba Dünya olarak adlandırırlar. Bende bu çizgide devam edeceğim. Çok sıradan olucak ama bir noktadan başlamam gerekiyor. Bu amaçla kendi bilgisayarımda java örneklerim için ayrı bir klasör açtım. Tüm örneklerimi burada yazıp geliştireceğim. Şimdi, aşağıdaki uygulama kodlarını notepad ile yazıp, JavaDunyam.java ismi ile kaydediyorum.[/FONT]
public class JavaDunyam
{
public static **** main(String[] args)
{
System.out.println("Java Dunayasına ilk adımımı attım galiba...");
}
}
[FONT=Verdana, Arial, Helvetica, sans-serif]Şimdi bu yazdığım kodu java derleyicisi ile derlemem gerekiyor. Hımmm. Peki ama benim java derleyicimin adresi nerede? Bir aramadan sonra kurmuş olduğum jsdk1.3.1_01 in klasörü içinde yer alan bin klasöründe, javac derleyici dosyasını buluyorum. Uygulamayı derlemek için önce bu klasöre komut satırından gittim. Sonuç tam anlamıyla hüsran hem bir hata mesajım var hemde bir programı derlemek için acaip bir yol kattetim. [/FONT]
[FONT=Verdana, Arial, Helvetica, sans-serif]
wol_error.gif
Bu resim yeniden boyutlandırıldı. Orjinal Boyutta görmek için buraya tıklatın. Resmin gerçek boyutları 669x182 ve büyüklüğü 6KB.
j24_1_6.gif
[/FONT]

[FONT=Verdana, Arial, Helvetica, sans-serif]Öncelikle hatayı araştırmam gerekiyor. Şimdi gidip kendime bir kahve almanın tam sırası. Anlaşılan bu kahve molamız çok uzun sürecek. Araştırmam sonucu kitapların vardığı en önemli ortak nokta şu oldu. Java, C dili ve türevleri gibi büyük küçük harf duyarlıklı bir dil. Dolayısıyla buradaki hata mesajından çıkan sonuç sınıf adı ile java uzantılı dosya adının bire bir aynı olması. Dikkat ediyorumda da benim dosya adım javadunyam.java ama kullandığım sınıf adı JavaDunyam. Diğer taraftan bu kadar hassa bir noktayı iyice araştırmam gerektiğini düşünüyorum. Bu kez şöyle bir komut veriyorum.[/FONT]
[FONT=Verdana, Arial, Helvetica, sans-serif]
wol_error.gif
Bu resim yeniden boyutlandırıldı. Orjinal Boyutta görmek için buraya tıklatın. Resmin gerçek boyutları 669x182 ve büyüklüğü 5KB.
j24_1_7.gif
[/FONT]

[FONT=Verdana, Arial, Helvetica, sans-serif]Derleyiciye dosya adını sınıf adı ile aynı şekilde veriyorum Bu kez herhangibir hataya maruz kalmadan uygulamanın derlendiğini düşünüyorum. Kontrol etmenin tek yolu var o da klasörün içibe bakmak. Evet java uzantılı dosyam, java derleyicim sayesinde, class uzantılı bytecode dosyası haline getirilmiş. Dikkat ettimde, dosya adı JavaDunyam. Yani sınıf adım ile birebire aynı. Burdan bir ders aldım, sınıf adım ile dosya adını birebir yazacağım bundan sonra. [/FONT]
[FONT=Verdana, Arial, Helvetica, sans-serif]
j24_1_8.gif
[/FONT]

[FONT=Verdana, Arial, Helvetica, sans-serif]Ancak burada hoşuma gitmeyen bir nokta var. Ben her seferinde, bin klasörüne mi gideceğim? Bu çok saçma olur. Kaynak kitaplar, bu konu ile ilgili olarak, bin klasörününün systemdeki path tanımlamalarına eklenmesi gerektiğini söylüyorlar. Bunun nasıl yapıldığına baktığımda son derece kolay bir işlem olduğunu gördüm. Xp kullandığım için, windows�un bu versiyonu üzerinde, path tanımının nasıl girileceğini inceledim. Control Panel� den, System penceresine buradada Advanced kısmına buradada Environmet Variables kısmına girdim. Zaten sistemde yüklü olan programlar nedeni ile burada bir Path tanımlaması vardı. Bunu edit ederek sonuna, jsdk�in kurulduğu klasördeki bin dizinini girdim.[/FONT]
[FONT=Verdana, Arial, Helvetica, sans-serif]
j24_1_9.gif
[/FONT]

[FONT=Verdana, Arial, Helvetica, sans-serif]Artık aynı java uygulamamı bulunduğu klasör içinden rahatça derleyebiliyorum. Bununla birlikte kaynak kitaplar, birde CLASSPATH adı verilen bir değerin daha girilmesi gerektiğini söylüyorlar. Bu değeri, sisteme sonradan java uygulamalarını yüklediğimizde, gerekli sınıfların otomatik olarak aranıp bulunması için yapıyormuşuz. Doğruyu söylemek gerekirse ne demek istediklerini henüz tam olarak anlamış değilim ama sanıyorumki ileride ortaya çıkacaktır. İstedikleri gibi olsun diyerek, bu tanımlamayıda aynı şekilde gerçekleştirdim. [/FONT]
[FONT=Verdana, Arial, Helvetica, sans-serif]
j24_1_11.gif
[/FONT]

[FONT=Verdana, Arial, Helvetica, sans-serif]Artık gerekli ayarlamaları yaptığıma ve uygulamayı başarılı bir şekilde derlediğime göre nasıl çalıştığına bakmatada yarar var elbette. Çünkü eski deneyimlerim, program kodunun başarılı bir şekilde derlenmesi ile, doğru bir şekilde çalışmasının tamamen farklı kavramlar olduğun göstermiştir hep. Doğru şekilde derlenipte mantıksal programlama hataları nedeni ile pek çok istenmeyen sonuç doğduğunu çok iyi biliyorum. Diğer yandan yazdığım bu bir kaç satırlık kod derlendiğine göre mantıksal olarak bir hata olmayacağından neredeyse eminim. Java ile yazılmış uygulamalara ait bytecode dosyalarını çalıştırmak için, yine bin dizininde bulunan java isimli programı kullanıyoruz. Ama bu sefet bin klasörüne gitmemize gerek yok neyseki. Çünkü path tanımını bu iş için güncelledik. İşte sonuç. Mükemmmel, olağanüstü bir program demeyi çok isterdim. Ama sadece A harfinin tabanındayız desem yerinde olur herhalde.[/FONT]
[FONT=Verdana, Arial, Helvetica, sans-serif]
j24_1_12.gif
[/FONT]

[FONT=Verdana, Arial, Helvetica, sans-serif]Artık program kodlarını incelem zahmetine girebilirim. Kahvemim bitmesinede az kaldı. İlk satırdaki tanımlamamız aslında bana çok tanıdık geldi. Özellikle C# ile yazılan programlardan. Nitekim Java dilide nesne yönelimli bir dil ve sınıf kavramının önemi bu basit kodda bile görünüyor. Bu dildede her şey sınıflar üzerine kurulmuş durumda. Kaynaklarıma baktığımda, sınıflar ile ilgili detaylı anlatımların yer aldığını görüyorum. Sanıyorum ki, ilerliyen kahve molalarımda bu konulara değinebileceğim. Public tanımlaması anladığım kadarı ile bu sınıfın başka sınıflar içerisindende çağırılabileceği anlamına geliyor ki öyle. Daha tanıdık gelen başka bir satır ise main yordamının olduğu satır. Main yordamı java dilindede, programın başlangıç noktası olarak görülüyor. Nitekim kodumuzu buraya yazdık. Acaba kim kime benziyor bilemiyorum. Arada pek fark yokmuş gibi geliyor ama Microsoft her zamanki gibi benzerliği usta bir pazarlama stratejisi ile ortadan kaldırıyor. Lütfen M harfinin iki varyasyındada kullanımına dikkat edelim.[/FONT]


Java

public static **** main(String[] args)
C#


static **** Main(string[] args)

[FONT=Verdana, Arial, Helvetica, sans-serif]Diğer yandan System.out.println ifadesi ise " işaretleri arasında yazılmış olan metni, komut penceresine yazdırıyor. Bu ise C# dilindeki WriteLine ile aynı işleve sahip. Aslında buradaki kodlar biraz oynamak lazım. Eminimki yeni ufuklar açacaktır. Öncelikle main yordamındaki, public kelimesini kaldırmak istiyorum. Bu durumda kodum aşağıdaki gibi görünecek. [/FONT]

public class JavaDunyam
{
static **** main(String[] args)
{
System.out.println("Java Dunayasına ilk adımımı attım galiba...");
}
}
[FONT=Verdana, Arial, Helvetica, sans-serif]Yazdığım uygulamayı derlediğimde hatasız bir şekilde derlendiğini gördüm. Class uzantılı dosyam oluşturulmuştu. Öyleyse her şey yolunda görünüyordu. Ama programı çalıştırdığımda hiçte öyle olmadığını gördüm. [/FONT]
[FONT=Verdana, Arial, Helvetica, sans-serif]
j24_1_13.gif
[/FONT]

[FONT=Verdana, Arial, Helvetica, sans-serif]Main metodunun public olması gerektiği sonucuna hemen varabildim. Aslında işi biraz daha ileri ***ürmek lazım. Neden başka bir sınıf yazıp, JavaDunyam sınıfı içinden bu sınıfa ait bir nesne örneği yaratmıyor ve bu sınıf içindeki bir metodu çağırmıyorum. Ne kadar zor olabilirki. Sonuçta java ile program yazarken kendimi C benzeri bir dil ile yazıyormuşum hissine kapılıverdim nedense. İşte JavaDunyam.java isimli kaynak dosyamın yeni kodları. [/FONT]

[FONT=Verdana, Arial, Helvetica, sans-serif]
public class JavaDunyam
[FONT=Verdana, Arial, Helvetica, sans-serif]{[/FONT]
[FONT=Verdana, Arial, Helvetica, sans-serif]public static **** main(String[] args)[/FONT]
[FONT=Verdana, Arial, Helvetica, sans-serif]{[/FONT]
[FONT=Verdana, Arial, Helvetica, sans-serif]System.out.println("Java Dunayasina ilk adimimi attim galiba...");[/FONT]
[FONT=Verdana, Arial, Helvetica, sans-serif]}[/FONT]
[FONT=Verdana, Arial, Helvetica, sans-serif]public **** Deneme()[/FONT]
[FONT=Verdana, Arial, Helvetica, sans-serif]{[/FONT]
[FONT=Verdana, Arial, Helvetica, sans-serif]System.out.println("JavaDunyam içinden bir ses ver bana...");[/FONT]
[FONT=Verdana, Arial, Helvetica, sans-serif]}[/FONT]
[FONT=Verdana, Arial, Helvetica, sans-serif]}[/FONT]
[/FONT]

[FONT=Verdana, Arial, Helvetica, sans-serif]Bu sınıf içinde Deneme isimli bir metod tanımladım. Amacım, bu metodu başka bir sınıf içinden çağırmak. Bu amaçla Diger isimli başka bir sınıfı Diger.java isimli dosya içinde aşağıdaki gibi tanımladım.[/FONT]
public class Diger
{
public static **** main(String[] args)
{
JavaDunyam jd=new JavaDunyam();
jd.Deneme();
}
}
[FONT=Verdana, Arial, Helvetica, sans-serif]Burada yaptğımı aslında C# ile yaptığım şeylerin aynısı. JavaDunyam sınıfı için bir nesne tanımladım. Sonrada nokta notasyonunu kullanarak, Deneme isimli metodu çağırdım. Şimdi bu kodları yeniden derleyip Diger isimli programımızı bir çalıştıralım. Bakalım herşey yolunda gidecek mi?[/FONT]
[FONT=Verdana, Arial, Helvetica, sans-serif]
j24_1_14.gif
[/FONT]

[FONT=Verdana, Arial, Helvetica, sans-serif]Daha güzel bir sonuç olamazdı. Sanıyorumki Java�yı öğrenmeye çalışırken çok zevk alacağım. Bakalım daha neler neler var. Kahvem bitmiş. Sanırım bir ara verme vakti. Bir sonraki kahve molasında bakalım neler olucak. [/FONT]


Geçtiğim hafta boyunca, Java ile ilgili kaynakları ve dökümanları incelemeye devam ettim. Her programlama dili için olmassa olmaz gerekli olan bir takım temel bilgileri araştırıyordum. Bunlar bir programcı için, dilin temel kullanımında ihtiyacı olduğu materyallerdir. Genelde her programlama dili için bunlar gereklidir. Ancak elbette bunlar programlama dilleri arasında farklılık gösterebilir. Bahsettiğim konu, değişkenler, koşullu ifadeler ve döngüler. Bu kahve molasında bunları işlemeye çalışacağım.

Java programlama dilinde değişkenlerin neler olduğunu bir tablo halinde hazırladım. Genelde programlama dilllerinde bu tip değişken tipleri hep tablolar halinde sunulur. Değişkenleri sıkça kullandıkça, bunların alt sınır, üst sınır ve alan büyüklükleri gibi bilgileri zamanla unutabiliriz. Şahsen ben hep unuturum. Ancak programlarımızı hazırlarken nerede en uygun değişken kullanılır bunuda bilmek isteriz. Ben oldum olası bu tip tabloları ezberleyemem. Zaten ezberleme taraftarı değilim. O nedenle bir sürü not defterim vardır ve taşıdığım çanta genelde ağır olur. Java dilinde kullanılan değişkenler içinde aynı şeyleri hissediyorum. Sanıyorumki bir tablo hazırlayacağım ve bunun güzel bir karton baskısını yanımda taşıyacağım.
Esasen Java dilinde, değişkenler, temel veri tipleri olarak anılırlar. Bu anlamda Java’da iki veri tipi olduğunu söyleyebiliriz. Değişkenlerin tanımanması için kullanılan Temel Veri Tipleri(Primitive) ve nesnelerin tanımlanması için kullanılan Referans Tipleri. C# dilinde’de bu böyledir zaten. Temel veri tipinden elde edilen değişkenler, bellekte yığın adı verilen bir bölgede tutulurlar. Oysa referans tiplerin tutuluş şekli daha farklı. Referans tipinden bir nesne, sahip olduğu üyülerin tutulduğu bellek bölgesindeki alanların başlangıç adresine işaret ederki bu tip nesneler yığında tutulurken, sahip oldukları içerik öbekte tululur. Java programlama dilinde Temel Veri Türleri aşağıdaki tabloda olduğu gibidir.



Görüldüğü gibi temel veri tipleri bunlar. Aslında bu tabloda birde alt aralık ve üst aralık bilgilerinin olması gerekiyordu. Ancak bunlar genelde kaynaklarda üstsel bilgi olarak gösterilmiş. Gerçekte, bu veri tiplerinin en üst ve en alt sınır bilgilerini küçük bir program kodu yazarakta öğrenebilirim. İşte küçük programım.
public class Sinirlar
{
public static **** main(String[] args)
{
System.out.println("Integer veri tipi");
System.out.println("Integer alt sınır :"+Integer.MAX_VALUE);
System.out.println("Integer ust sınır :"+Integer.MIN_VALUE);
System.out.println("---");

System.out.println("Double veri tipi");
System.out.println("Double alt sınır :"+Double.MAX_VALUE);
System.out.println("Double ust sınır :"+Double.MIN_VALUE);
System.out.println("---");

System.out.println("Float veri tipi");
System.out.println("Float alt sınır :"+Float.MAX_VALUE);
System.out.println("Float ust sınır :"+Float.MIN_VALUE);
System.out.println("---");

System.out.println("Long veri tipi");
System.out.println("Long alt sınır :"+Long.MAX_VALUE);
System.out.println("Long ust sınır :"+Long.MIN_VALUE);
System.out.println("---");

System.out.println("Short veri tipi");
System.out.println("Short alt sınır :"+Short.MAX_VALUE);
System.out.println("Short ust sınır :"+Short.MIN_VALUE);
System.out.println("---");

System.out.println("Byte veri tipi");
System.out.println("Byte alt sınır :"+Byte.MAX_VALUE);
System.out.println("Byte ust sınır :"+Byte.MIN_VALUE);
System.out.println("---");
}
}
Şimdi yazdığım uygulamayı Java Derleyicisi ile derliyorum. Hayret, her hangibir hata vermeden derledi. Daha sonrada programı çalıştırıyorum. Sonuç gayet güzel oldu. Tam istediğim gibi, temel veri türlerine ait alt ve üst sınır değerlerini elde etmeyi başardım. Bunu yaparken, bu veri tipleri için Java içinde geliştirilmiş hazır sınıfları kullandım. Örneğin int veri tipi için Integer sınıfını kullandım. Aslında tüm temel veri tipleri için sınıflar mevcut. Tek yaptığım bu sınıfların MAX_VALUE ve MIN_VALUE özelliklerinin değerlerini ekrana yazdırmak oldu. Bu kadar basit.

j24_2_1.jpg


Burada aslında önemli bir noktada her veri tipi için bir sınıfın var olması. Dolayısıyla bir değişken tanımlamasını iki şekilde yapma imkanına sahibim. Örneğin aşağıdaki kod parçasında, int (integer-tamsayı) veri tipinden iki değişkenin farklı şekillerde tanımlandığını görüyoruz.
public class DegTan
{
public static **** main(String[] args)
{
int deger1=45;
Integer deger2=new Integer(50);

System.out.println("deger1 "+deger1);
System.out.println("deger2 "+deger2);
}
}
Bu uygulamayı çalıştırdığımda aşağıdaki sonucu elde ettim.

j24_2_2.gif


Sonuçta iki tane integer tipinde değişken tanımlamıştım, ancak bu tanımlamalar arasında büyük farklar olduğuna inanıyorum. Şimdi bunu araştırmam gerektiğini düşünüyorum. İlk başta gözüme çarpan, Integer sınıfını kullanarak, integer tipte veriyi barındıran Deger2 isimli bir nesne tanımlamamız. Bu durumda deger2 değerinin bellekte tutuluş şekli, deger1’den farklı olmaktadır. Diğer yandan tüm temel veri tiplerinin birer sınıfı mevcuttur ve bu sınıflar java.lang adı verilen bir pakette bulunmaktadırlar. Kaynaklardan edindiğim bilgiye göre, burada adı geçen paket kavramının, C#’taki namespace (ad alanı) kavramı ile aynı olduğu sonucuna vardım. Bu bilgiye ulaşmak benim için internette biraz zaman harcamak ile gerçekleşti. Java için herzaman elimizin altında bulunması gereken yardım dokumantasyonu olan Java 2 Platform Std.Ed. ********ation v1.3.1’ i
http://java.sun.com/j2se/1.3/docs.html
adresinden indirdim. Bu döküman yaklaşık olarak 22 megabyte’lık bir zip dosyası. Açıldığında, html dokumatasyonuna ulaşabiliyorsunuz. Burada aradığım hemen her konuya ait bilgi mevcut. Ancak bazı konuların yanında web pages yazılı. Bunlar internetten online olarak bakılabilecek yada indirilebilecek adreslere işaret ediyor. İşte, java.lang paketinin içeriğinede bu dokmantasyondan ulaştım. Temel veri tiplerine ait sınıfları kullanarak pek çok fonksiyonu kullanma şansına sahip olduğumu gördüm. Örneğin, ilk örneğimizde kullandığımız MAX_VALUE ve MIN_VALUE özellikleri gibi. Yada integer değeri String’e dönüştürmek için kullanılan toString metodu ve daha pek çok sayısız metod yer alıyor.
Bir diğer konuda, Java’daki temel veri türünden değişkenler ile, referans türünden nesneler arasındaki temel farklılıklar. Burada önemli olan konu, bu iki veri türününde bellekte farklı şekillerde tutuluyor olması. Temel veri türünden olan değişkenler bellekte kendi isimleri ile stack(yığın) adı verilen bölgede tutuluyorlar. Referans tipinden olan nesneler ise, belleğin heap(öbek) adı verilen bölgesinde tutuluyor. Tanımlanan referans tipindeki nesne, öbekte yer alan verilerine işaret eden ve yığında tutulan bir değişken adına sahip oluyor. Bu kavramlar aslında karmaşık gibi görünsede, nesneler arasındaki atamalarda önemli sonuçlar doğuruyor. Bunu açıklamak için örnekler geliştirmek sanıyorumki en doğrusu olucaktır. Bu örnekte yapmak istediğim, bir sınıf hazırlamak ve bu sınıf içinde değişkenler tanımlamak. Sonra bu sınıfa ait bir nesne örneği yaratacak ve onu aynı sınıftan türetilen başka bir sınıfa atayacağım. Bu işlemlerin gerçekleşmesi halinde bellekteki oluşucak hareketleri ise şekille göstermeye çalışacağım. Öncelikle örneğimi geliştireyim. İlk önce nesnelerim için kullanacağım sınıfımı oluşturuyorum.
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 **** Yaz()
{
System.out.println("Deger1 :"+Deger1);
System.out.println("Deger2 :"+Deger2);
}
}

Doğruyu söylemek gerekirse bu kodlar bize çok şey söylüyor. Buradaki kodları tamamen C#’taki bilgimi kullanarak yazdım. Örneğin sınıfı tanımlaması içinde, iki adet yapıcı (constructor) metod var. İlki Deger1 ve Deger2 isimli değişkenlerimize 0 değerlerini atıyan parametre almayan ve sınıflar için varsayılan olarak kabul edilen yapıcı metodumuz. Diğeri yapıcı metodumuz ise, bu değişkenlere aldığı parametre değerlerini atıyor. Birde Yaz isimli bir metodumuz var. Bu metod ise, sınıfımızın Deger1 ve Deger2 isimli integer değişkenlerini komut satırına yazdırıyor. Yapıcı metodların kullanımı, sınıflar içindeki yeri gibi kavramlara şimdilik göz ucu ile bakmış oldum. Bu kavramları ve daha fazlasını diğer kahve molalarımda incelemek istiyorum. Hazır kahve demişken, kahvemi tazelesem iyi olucak sanırım. Gelelim diğer sınıfımıza. Bu sınıfımız ise Sinifim sınıfı türünden nesneler üzerinde işlem yapmak için kullanılıyor.

public class Program
{
public static **** main(String args[])
{
Sinifim sf1=new Sinifim(10,20);
System.out.println("Sf1 nesnesi için");
sf1.Yaz();

Sinifim sf2=new Sinifim();
System.out.println("Sf2 nesnesi için");
sf2.Yaz();

System.out.println("sf1 nesnesi, Sf2 nesnesine aktarılıyor");
sf2=sf1;
sf2.Yaz();

}
}

Bu kodlarla göstermek istediğim, referans tipleri arasındaki atamalar sonucu oluşan ilişkidir. Program içinde, önce sf1 isimli bir nesne örneği oluşturuluyor ve bu nesne içindeki Deger1 ve Deger2 integer değişkenlerine 10 ile 20 değerleri atanıyor. Bu durumda belleğin durumunun tasviri aşağıdakine benzer olucaktır.

j24_2_3.gif


Daha sonraki adımda ise, sf2 isimli başka bir Sinifim nesne örneğini oluşturuyoruz. Bu kez nesneyi, Sinifim sınıfının varsayılan yapıcı metodu ile oluşturuyor ve değişkenlerimize 0 değerini atıyoruz. Bu halde, belleğin durumu şu şekilde olucaktır. Bellekte Sinifim, sınıfı türünden iki adet nesne örneği mevcuttur.


j24_2_4.gif


Buraya kadar herşey normal. Ancak son adımda, sf1 , nesnesini sf2 nesnesine atıyoruz. İşte bu durumda olay biraz daha değişik bir hal oluyor. Nitekim, sf1 nesnemiz artık sf2 nesnemize işaret ediyor.

j24_2_5.gif


Şimdi örneğimizi biraz değiştirelim ve Sinifim sınıfına aşağıdaki DegerAta isimli metodu ve kod satırlarını ekleyelim.
public **** DegerAta(int d1,int d2)
{
Deger1=d1;
Deger2=d2;
}
Şimdide Program sınıfına aşağıdaki kod satırlarını ekleyelim.
sf1.DegerAta(1,2);
sf1.Yaz();
sf2.Yaz();
Bu haldeyken, Program dosyasını çalıştırdığımda, her iki nesne örneğininde aynı değerleri yazdırdığını görürüz. Bu şu anlama geliyor. Atama işleminden sonra, öbekteki aynı bölgeyi işaret eden bu iki nesneden birisinin içindeki değerlerin değiştirilmesi, diğer nesneninde aynı değişiklikleri işaret etmesi anlamına gelmektedir. Sonuç aşağıdaki gibi olucaktır.

j24_2_11.gif


Değişkenler arası atamalara gelince. Burada durum referans tiplere göre daha farklı. Çünkü değişkenler oluşturuldukları isim ile bellekte tutulur. Bu konuyuda bir örnek üzerinde incelemek taraftarıyım. Kısa ve basit bir örnek bize yeterli olucaktır sanırım.
public class Program2
{
public static **** 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 derlediğimde hiçte beklemediğim bir hata ile karşılaştım.

j24_2_6.gif


Sanıyorumki hatanın sebebi Deger2 isimli integer veri tipindeki değişkene ilk değer atamasını yapmamış olmamdı. Bu durumda kodun bu satırını aşağıdaki gibi değiştirdim ve programın başarılı bir şekilde derlendiğini gördüm.
int Deger2=0;
Şimdi uygulamamı çalıştırdığımda aşağıdaki sonuçlar ile karşılaştım.


j24_2_7.gif


Şimdi kodu güzelce bir incelemem gerektiğini düşünüyorum. Kahvemden bir yudum aldım ve Javaca düşünmeye başladım. İlk olarak Deger1 ve Deger2 değişkenlerimizi tanımlıyor ve bunlara ilk değer olarak sırasıyla 50 ve 0 değerlerini atıyoruz. Bu noktada belleğin durumu aşağıdaki tasvirde olduğu gibi olucaktır. İki ayrı integer tipte değişken belleğin yığın bölgesinde yerlerini almıştır.

j24_2_8.gif


Daha sonraki adımda ise, Deger1 değişkeninin değeri Deger2’ye atanıyor. Bu durumda Deger1’in sahip olduğu 50 değeri, Deger2 değişkenine atanmış ve belleğin görünümü aşağıdaki şekilde olmuş oluyor.

j24_2_9.gif


Son adımda ise, Deger1’ değişkenine 48 değerini atıyoruz ve bellekteki Deger1 değişkeninin değerinin değişmesine neden oluyoruz. Referans tiplerinde olduğu gibi, değişken tanımlamalarında, atamadan sonraki değişiklikler, değişkenlerin birbirlerini etkilemesine neden olmamaktadır.

j24_2_10.gif


Sanıyorumki değişken tipleri ve referans tipleri arasındaki farkları daha iyi anladık. Evet alet çantamızı doldurmaya devam edelim. Bizim için gerekli olan diğer önemli ve hatta çok önemli unsurlar koşullu ifadeler ve döngülerdir. Bu her programlama dili için böyledir. Öncelikle karşılaştırma ifadelerine bir göz atmak istiyorum. Karşılaştırma ifadelerimiz bana nedense çok tanıdık geliyor. If ve Switch. Bu ifadelerin kullanımını örnekler ile incelemek taraftarıyım. Öncelikle if koşul ifadesini incelemek istiyorum.

public class Kosullar
{
public static **** main(String args[])
{
int Not;
Not=49;
if(Not>50)
{
System.out.println("Sınıfı geçtin...");
}
else if((Not>45)&&(Not<50))
{
System.out.println("Kanaat kullanmalımıyım bakayım?");
}
else
{
System.out.println("Sınıfta KALDIN?");
}
}
}

Aslında her şey çok açık ve ortada. If koşulları parantezler içinde yazılır ve karşılaştırma sonucu true ise hemen izleyen { } kod bloğu içindeki kodlar çalıştırılır. Eğer bu şart false ile sonuçlanır yani gerekli koşul sağlanmaz ise, varsa bir sonraki else koşuluna geçilir. Burada kullanmış olduğumuz bir takım karşılaştırma operatörleride mevcut. Java’da kullanılan karşılaştırma operatörlerü aşağıdaki tabloda yer almaktadır.


 

gölge_adam

Katılımcı Üye
20 Şub 2007
517
8
TeXaS
Diğer yandan ifadelerimizin birisinde && kullandık. Bu mantıksal VE anlamına gelen bir operatördür. Bu tip mantıksal operatörleri, iki veya daha fazla koşulun sonuçlarını bir arada değerlendirmek istediğimizde kullanırız. Bu örneğimizde mantıksal operatörümüz, belirtilen iki şartında doğru olması şartıyla izleyen kod bloğundaki kodları çalıştırmaktadır. Java’da kullanılan mantıksal operatörler aşağıdaki gibidir.

Kaynaklardan mantıksal operatörlerden && ve || için farklı bir kullanım tarzı daha olduğunu öğrendim. Buda & ve | operatörleri. Bu iki kullanım tarzı arasındaki farkı incelediğimde oldukça işe yarar bir sonuçla karşılaştım. && ve || operatörleri, her iki koşulunda işleme sokulmasını sağlar. Ancak bazen ilk koşulun true olması yada false olması sonucu belirlemek için yeterlidir. Böyle bir durumda her iki koşuluda karşılaştırmaktansa, yani koşul ifadesindeki tüm kodu çalıştırmaktansa, & ve | operatörlerini kullanarak, sadece soldaki koşula bakılmasını ve buna göre karar verilmesini sağlayabiliriz. Gelelim switch koşullu ifadesinin kullanımına. Bunuda yine bir örnekle incelemek en güzeli.
public class Kosullar
{
public static **** main(String args[])
{
int Deger1=3;

switch(Deger1)
{
case 1:
{
System.out.println("Birinci sınıf nesnesi oluştur.");
break;
}
case 2:
{
System.out.println("Ikinci sınıf nesnesi oluştur.");
break;
}
case 3:
{
System.out.println("Ucuncu sınıf nesnesi oluştur.");
break;
}
default:
{
System.out.println("Ana menuye don.");
break;
}
}
}
}
Aslında buraya kadar herşey çok hızlı gelişti. Nitekim kullanılan materyaller C dilinden gelmekte ve C# dili içindede aynen kullanılmakta. Bu nedenle bir C# programcısı için Java’yı öğrenmek veya bir Java programcısı için, C# dilini öğrenmek hızlı oluyor diyebilirim. Neyse kahvemizi yudumlamaya devam edelim.
Sırada döngüsel ifadeler var. Bazen bir işlemi birden fazla sayıda uygulamak isteyeceğimiz durumlar olabilir. Gauss eğer bir bilgisayara sahip olsaydı inanıyorum ki 1’den 100’e kadar olan sayıların değil 1’den 1000’e kadar olan sayıların 4ncü dereceden kuvvetlerinin toplamını bulan bir uygulama geliştirir ve bizi Gauss formüllerini ezberlemekten kurtarırdı. Sanıyorum programlama dillerini geliştirenler Gauss’un çektiklerinden çok, okul yıllarında matematik sınavlarındaki Gauss formüllerini hatırlayamamaktan çekmişler. Burada, for döngüsü kullanarak bu işlemin nasıl gerçekleştiğini incelemeye çalışacağım. Burada üs almak için, Java içinde yer alan Math sınıfına ait pow isimli metodu kullandım.
public class Dongu
{
public static **** main(String args[])
{

double Toplam=0;

for(int i=1;i<=1000;i++)
{
Toplam=Toplam+(Math.pow(i,4));
}

System.out.println(Toplam);
}
}


For döngüsü dışında iki döngü çeşidi daha vardır. Bunlar while döngüleridir. İki çeşit while döngüsü vardır. Bunlardan birisi, ilk başta koşulu kontrol eder ve koşul sağlanıyorsa döngü içindeki kodları çalıştırır. Diğer çeşidinde ise, döngü içindeki kodlar en az bir kere çalışır ve koşul sonradan kontrol edilir. Her iki döngüde koşullar sağlandığı sürece devam eder. Örneğin yukarıdaki uygulamamızı while döngüsü kullanarak gerçekleştirelim.


Toplam=0;
int i=1;
while(i<=1000)
{
Toplam=Toplam+(Math.pow(i,4));
i++;
}
System.out.println(Toplam);
While döngümüzün diğer şekli ilede bu döngüyü yazabiliriz.
Toplam=0;
int j=1;
do
{
Toplam=Toplam+(Math.pow(j,4));
j++;
}
while(j<=1000);
System.out.println(Toplam);
Artık hakiki bir mola vermenin zamanı geldi sanırım. Bu kahve molasında, alet çantamızı iyice doldurduk. Ancak bu çantaya doldurmamız gereken daha çok parça olduğu kesin

Hemen her programlama dilinde olduğu gibi dizilerinde java�da sıkıcı bir yeri var. Sıkıcı olmasını nedeni belkide, veri saklama ile ilgili olarak günümüz teknolojilerinin getirdiği veritabanı, xml, gelişmiş koleksiyonlar gibi kavramların çok daha fazla tercih ediliyor olması. Ancak ne olursa olsun, hangi programlama dili olursa olsun ve kavramları ne kadar sıkıcı olursa olsun, bunları bilmekte, incelemekte fayda var.Bu sabah saatlerindeki kahve molamda, dizilerin Java programlama dili içindeki yerini incelemeye çalışacağım. Bir diziyi belkide en güzel şu şekilde tanımlayabiliriz.
Dizi, belli bir sayıda ve aynı veri türünden değişkenlere, aynı isim altında erişilmesini sağlayan bir referanstır. Aslında bu tanım içerisinde çok geniş kavramlar var ve açıklanması gerekli. Herşeyden önce, dizilerin referans olduklarını söylüyor. Java dilindede, C#�ta olduğu gibi diziler referans tipli verilerdir. Dolayısıyla bir dizi, belleğin yığın (stack) kısmında tutulurken, dizi elemanlarının tamamı, öbek (heap)�te yer alır. Yani dizinin adı, öbekteki elemanların başlangıç adresine işaret eder. Bu dizilerin en önemli unsurlarından birisidir. Diğer yandan, diziler aynı veri türünden elemanlara sahip olmalıdır. Bununla birlikte dizilerin eleman sayısıda oluşturulurken belirlenir. Dolayısıyla, bir diziyi en baştan boyutlandırdığımızda, beliltilen sayıda elemanı aktarabiliriz ve buda dizinin boyutu ile dinamik olarak oynamamızı engeller. Doğruyu söylemek gerekirse bu kısıtlamalar belkide C# dilinde koleksiyonları geliştirilmesine ve daha çok önem kazanmasına neden olmuştur. Kimbili belki Java dilinde�de koleksiyonlar var. Şimdilik karşıma çıkmadılar.
O halde işe referans veri tipi olan dizilerin nasıl tanımlanacağından başlamak gerekiyor. Referans tipli olması, dizilerin oluşturulurken new yapılandırıcı kullanılarak oluşturulması gerektiği sonucunu ortaya çıkartıyor. Nitekim, diziler referans tipli nesnelerdir. Dolayısıyla bir sınıf örneği olmak zorundalar. Ancak diğer yandan, bir diziyi oluştururken new yapılandırıcısını kullanmak zorunda değiliz. Dizi elemanlarına, 0 tabanalı bir indis sistemi ile erişebilmekteyiz. Bu anlamda dizilerin, döngüler ile kardeş olmalarını gayet iyi anlayabiliyorum. Şimdi dizi kavramını incelemek için basit ama hızlı bir örnek geliştirmek düşüncesindeyim. Kahvemden bir yudum alıyorum ve aşağıdaki örneği yazıyorum. public class Dizi
{
public static **** main(String[] args)
{
int dizi1[]=new int[10];
for(int i=0;i<dizi1.length;++i)
{
dizi1=i*2;
System.out.println((i+1)+". eleman="+dizi1);
}
}
}
Uygulamayı başarı ile derledikten sonra çalıştırdığımda aşağıdaki sonucu aldım.

j24_3_1.gif


Kodların çalışma sistematiği oldukça basit. Diziyi tanımlaka için new yapılandırıcısını kullandık ve dizinin integer veri tipinden 10 elemanlı olmasını sağladık. Bu noktadan sonra dizimize elemanlar atamak için bir döngü kullandık. Bu döngü dizimizin boyutuna kadar hareket eden ve her bir elemana indis değerinin iki katını aktaran bir yapıda. Kullandığımız length özelliği, dizilerin boyutunu elde etmekte kullanılmakta. Buradanda zaten, dizilerin bir Java sınıfına ait olduğu sonucuna varabiliriz. Kodumuzda, dizi elemanlarını okumak içinde aynı döngü içindeki dizi1 şeklindeki yazımı kullandık. Dizileri yukarıdaki örnekte olduğu gibi new yapılandırıcısı ile tanımlayabileceğimiz gibi, başka alternatif bir yoluda kullanabiliriz. Benzer bir örnek uygulam aşağıda yer alıyor.
public class Dizi2
{
public static **** 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);
}
}


j24_3_2.gif


Burada diziyi tanımlarken elemanlarınıda baştan atamış olduk. Bu aynı zamanda verdiğimiz eleman sayısına göre dizinin otomatik olarak boyutlandırıldığınıda göstermektedir. Son örneğimizin bellekteki yerleşim planına göz atarsak aşadıdaki tasvire benzer bir yapının oluştuğunu görürüz.

j24_3_3.gif


Peki ya bir diziye taımlandığı veri tipinden başka bir tipte eleman eklemeye kalkarsak ne gibi sonuçlarla karşılaşabiliriz. Doğrusu bunu merak ediyorum. Bu nedenle yukarıdaki örnekte, integer tipteki dizimize, başka bir veri tipinden eleman eklemeye karar verdim. Bu amaçla, �a� karakterini sincizce dizi elemanları arasına yerleştirdim.
public class Dizi2
{
public static **** main(String[] args)
{
int[] dizi={1,3,5,7,9,11,�a�,15};
for(int i=0;i<dizi.length;++i)
{
System.out.println((i+1)+". eleman="+dizi);
}
}
} Uygulamayı derlediğimde her hangibi hata mesajı ile karşılaşmadım. Diğer yandan uygulamayı çalıştırdığımda aşağıdaki hata mesajı beni bekliyordu.


j24_3_4.gif



Vouv! Hiç beklemediğim bir durum. 7nci eleman yani �a� değerinin karakter karşılığı oluvermişti bir anda. Hımm. Aslında bu istemediğim bir sonuç. Ben daha çok bir hata mesajı bekliyordum. Yoksa dizi tanımında bir tanımlama hatasımı yaptım? Denemeye devam etmeye karar verdim. Sabahın kaçı olursa olsun ben bu hata mesajını bulacaktım. Kodları aşağıdaki şekilde değiştirdim. Aklıma ilk gelen integer değilse bir double değeri buraya koymak oldu. Hatta bir tane değil bir kaç farklı veri tipinden değerler koymak.
public class Dizi2
{
public static **** 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);
}
}
} Sonunda başardım. İstediğim hata mesajlarını aldım ve dizi tanımına sadık kaldım.

j24_3_5.gif



Ancak dizileri kullanırken başıma gelebilecek diğer hatalarıda incelemek istiyorum. Öncelikle dizide olmayan bir indis elemanı oluşturmak istersem veya ona ulaşmak istersem ne olur? Fazla söze gerek yok hemen kodları yazmak lazım. Bu kez 5 elemanlı bir diziye 6ncı elemanı eklemeye çalışacağım.
public class Dizi2
{
public static **** main(String[] args)
{
int[] dizi={1,2,3,4,5};
for(int i=0;i<dizi.length;++i)
{
System.out.println((i+1)+". eleman="+dizi);
}
dizi[6]=7;
}
} Uygulama yine hatası olarak derlendi. Umarım bu sefer çalıştırdığımda istediğim hatayı alabilirim. Evet. Mükemmel. Hatayı elde etmeyi başardım.

j24_3_6.gif


Dizileri tanımlarken, aynı veri türünden elemanları grupladığımızdan bahsetmiştik. Farklı bir durum daha vardır. Bu da bir diziyi Java dilinin en üst sınıf olan (C# taki gibi) Object türünden tanımlamak ve elemanları birer nesne olarak belirlemektir. Bu teknikte, dizinin tüm elemanları birer nesnedir. Bu anlamda bellekteki dizilişte farklı olmaktadır. Öyleki, Object türünden bir dizi tanıladığımızda, dizinin elemanları öbekte tutulurken her bir eleman nesne olduğu için, yine öbekteki asıl alanlarına referans eden değerleri taşırlar. Ancak dizi elemanlarına eriştiğimizde, bu nesnelerin referans ettikleri öbek alanlarındaki verilere ulaşılır. Hemen bununla ilgili bir örnek yapmakta fayda var.
public class DiziObject
{
public static **** main(String[] args)
{
Integer eleman1=new Integer(456);
String eleman2=new String("Ben bir stringim...");
Double eleman3=new Double(45.45687);
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);
}
}
} Burada yaptığım Object türünden dizim için, new yapılandırıcılarını kullanarak sırasıyla integer, string, double ve boolean veri türlerinden birer nesne yaratmak ve daha sonra bu nesneleri Object türünden diziye aktarmak. Uygulama başarılı bir şekilde derlenicektir ve çalışacaktır.

j24_3_7.gif


Bu tekniğin bellekteki görünümü ise aşağıdaki tasvire benzer şekilde olucaktır

j24_3_8.gif


Tabi burada aynı örneği aşağıdaki şekide geliştirmeyide düşündüm ama bu durumda hata mesajları ile karşılaştım. Çünkü aşağıdaki tekniği uygulayarak bir Object dizisi oluşturmaya çalıştığımda, elemanların her biri birer değişken olarak algılandı ve Object dizisine eklenmeye çalışılmak istendi. Ancak Object türünden bir dizi, kendisi gibi nesne elemanlarını kabul edeceğinden temel veri türlerinden tanımlanmış değişlenleri kabul etmedi ve derleyici bir sürü hata mesajı verdi.
public class DiziObject
{
public static **** 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);
}

j24_3_9.gif


Ancak burada dikkat etmemiz gereken bir nokta var. O da, String tipteki "Ben bir stringim" için bir hata mesajı almamış olmamız. Bunun nedeni aslında çok açık. Nitekim String veri türü, bir referans türüdür. Dolayısıyla new yapılandırıcısı ile bir String nesnesi yaratabiliriz. Bununla birlikte new yapılandırıcısın kullanmadan yukarıdaki gibi bir string tanımlamakta yine aynı işlevi gerçekleştirecektir. Sanırım burada bir dip not olarak şu iki ifadeninde eşit olduklarını söyliyebiliriz.
String s=new String("Merhabar"); String s="Merhaba"; Gelelim diziler ile ilgili ne tür işlevleri gerçekleştirebileceğimize. Dizilerin Java�nın bir sınıfı olduğu söylemiştik. Evet, diziler aslında, java.util.Arrays sınıfının örneklenmiş nesneleridir. Geçen kahve molamdada internetten indirdiğim jsdk dökümanları içinde bu sınıfı aradım ve sayısız pek çok metodunun olduğunu gördüm. Bunların hepsini incelemek için sanıyorumki bir kaç hektar kahve tarlamın olması, bunları öğütücek ve işlemden geçirerek sütlüsünü, 5 şekerlisini çıkartıp bana sunacak bir fabrikam olması gerekiyor. Ama sanıyorumki bu kahve molasında en çok işime yarayacakları incelesem iyi olur. İlk gözüme çarpan aynı isimli metodlardan hemen her veri türü için aşırı yüklenmiş varyasyonların oluşuydu. Örneğin sort metodunu ele alalım. Adındanda anlaşılacağı üzere bu metod dizi elemanlarını sıralıyor. Elbette dizinin tipine bağlı olarak gerçekleştirilen bir sıralama bu. Aşağıdaki örnekte, integer değerlerden oluşan bir diziyi şu metod prototipini kullanarak sıralattım.
public static **** sort(int[] a) Şimdide kodlarımızı yazalım.
import java.util.*;

public class DiziSirala
{
public static **** 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);
}
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);
}
}


j24_3_10.gif


Burada öncelikle Arrays.sort metodunu kullanarak sıralam işlemini yapmak için, java.util paketini import anahtar kelimesi ile uygulamamıza ekledik. Bu C# taki namespace�lerin using ifadesi ile eklenmesi ile aynı şey. Integer veri türleri için tasarlanmış bu metodun diğer veri türleri için aşırı yüklenmiş versiyonlarıda mevcut. Burada metodumuz parametre olarak dizinin adını alıyor ve dizinin tipine bakarak uygun olan sort metodunu çalıştırıyor. Sort metodunun bir diğer versiyonuda aşağıda prototipi verilen versiyondur.
public static **** sort(int[] a,int fromIndex,int toIndex) Bu aşırı yüklenmiş versiyona göre, dizinin sadece belirli indisler arasındaki elemanlarının sıralanmasını sağlamış oluyoruz.Bunu yukarıdaki örneğimize uygularsak;
import java.util.*;

public class DiziSirala
{
public static **** 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);
}
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);
}
}


j24_3_11.gif


Bir diğer ilginç metod ise BinarySearch metodu. Sort metodunda olduğu gibi bu metodda diğer tüm veri türleri için aşırı yüklemiş. Prototipi aşağıdaki gibi olan bu metod, dizi içindeki bir elemanın var olup olmadığına bakıyor ve buna göre bir sonuç döndürüyor.
public static int binarySearch(int[] a,int key) Şimdi bu metod ile ilgili bir deneme yapmanın tam sırası. import java.util.*;

public class DiziBul
{
public static **** 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);
}
System.out.println("");
int sonuc=Arrays.binarySearch(dizi,56);
System.out.println("Arama sonucu "+sonuc);
}
} İlk sonuçlar hiçte iç açıcı olmadı benim için. Herşeyden önce aşağıdaki gibi anlamsız bir sonuç elde ettim.


j24_3_12.gif


Dökümantasyonu yeniden incelediğimde herşeyin sebebi anlaşılıyordu. BinarySearch metodunu kullanabilmem için, dizinin mutlaka sıralanmış olması gerekiyor. Bu nedenle koda, sort metodunuda ekledim. Bu durumda, dizimizin sıralanmış hali üzerinden arama işlemi başarılı bir şekilde gerçekleştirilmiş oldu. BinarySearch metodunun çalıştırılıması sonucu dönen değer, aradığımız elemanın dizi içindeki indis numarasıdır.
import java.util.*;

public class DiziBul
{
public static **** 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);
}
System.out.println("");
Arrays.sort(dizi);
int sonuc=Arrays.binarySearch(dizi,56);
System.out.println("Arama sonucu "+sonuc+".eleman"+dizi[sonuc]);

j24_3_13.gif
 

gölge_adam

Katılımcı Üye
20 Şub 2007
517
8
TeXaS
Şimdi daha değişik bir durumu inceleyelim. Eğer dizi içinde olmayan bir eleman ararsak binarySearch metodu nasıl bir sonuç döndürecektir. Bu amaçla aşağıdaki kodu hazırladım. Örnek içinde, iki adet negatif ve iki adet pozitif tamsayıyı dizi içerisinde arattım. Bu elemanların hiçbirisin dizinin bir elemanı değil. Sonuçlara baktığımda dizide olmayan pozifit elemanlar için -12 değerini, dizide olmayan negatif elemanlar için ise -1 değerini elde ettim. Pozifit ve negatif elemanlar için binarySerach metodunun döndürdüğü değerler farklı olmasına rağmen ikise negatiftir. Dolayısıyla negait olmaları dizinin elemanı olmadıklarını göstermektedir.
import java.util.*;

public class DiziBul
{
public static **** 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);
}
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);
}

j24_3_14.gif


Demekki binarySearch metodunu bir if koşulu ile kullanarak aranan elemanın dizi içerisinde olup olmadığını belirleyebiliriz.
import java.util.*;

public class DiziBul
{
public static **** 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
);
}
System.out.println("");
Arrays.sort(dizi);
int sonuc1=Arrays.binarySearch(dizi,156);
if(sonuc1<0)
{
System.out.println("BULUNAMADI");
}
else
{
System.out.println("BULUNDU");
}
}

j24_3_15.gif


Arrays sınıfı ile ilgili daha pek çok metod vardı ve bunlarıda incelemek istiyordum. Ama hava aydınlanmaya ve içmeyi unuttuğum kahvemde ice-cafe olmaya başlamıştı. Sanırım ara vermek için en uygun zaman. Biraz dinlenmeyi hakkettik. İlerleyen kahve molalarında kahvemi içmeyi unutmayacağım.


j24_4_3.gif


Görüldüğü gibi yapıcı metodlarımızda dikkat çeken ilk özellik, sınıf adı ile aynı olmaları. Ancak burada karşılaştığım ilginç bir durum oldu. Yapıcı metodların nasıl kullanıldığı ile uğraşırken, varsayılan yapılandırıcıyı tanımlamadığım aşağıdaki örneği yazdım.
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;
}
public **** Yaz()
{
System.out.println("Deger1:"+deger1+" Deger2:"+deger2);
}
} public class Prog
{
public static **** main(String[] args)
{
OverloadDeneme Nesne=new OverloadDeneme();
Nesne.Yaz();
}
}
Prog isimli sınıfımı derlemeye çalıştığımda aşağıdaki hata mesajı ile karşılaştım.

j24_4_4.gif


Bir anda ne olmuştuda, new yapılandırıcısı ile basit bir nesne yaratma işlemi hata ile sonuçlanmıştı. Heyecanla ve birazda tedirgin bir havayla, kaynaklarımı hızlı hızlı karıştırmaya başladım. Sonrada Java’nın çok güzel inceliklerinden birini farkettim. Normalde Java, varsayılan yapıcı metodları bir sınıf için yazmassak bizim için bir tane hazırlıyordu. Ancak özelleştirilmiş (parametreler alan) yapıcı metodlar tanımladığımızda, bizim tam anlamıyla konunun hakimi olduğumuzu düşünerek bu varsayılan yapılandırıcıyı otomatik olarak tanımlama desteğini bir anda çekiveriyordu. Tabir yerinde ise bizimle bu konuda muhatap bile olmuyordu. Dolayısıyla varsayılan yapıcı metoduda bizim tanımlamamız gerekiyordu. Bu güzel incelikten yola çıkarak uygulamayı düzelltim ve hata mesajını ortadan kaldırdım.
C# dilini öğrenmeye ilk başladığım zamanlar üniversite yıllarında öğrettikleri C++ dilindeki büyük küçük harf ayrımında her zamanki gibi ilk başlarda çok unutkanlıklar yaşamış ve hep hatalar yapmıştım. Ama şimdi Java’da gördümkü, unutkanlığa asla yer yok hatta tam anlamıyla dile hakim olmak esas.
Neyse yapılandırıcıların bu özellikleri ve işlevlerinden sonra, acaba kendi sınıfımız için özel bir yapılandırıcıya gerek var mı diye düşünmeye başladım. Bu sınıfa ait nesneler, tablo satırlarını gösterecek olduğundan, yapılandırıclara parametre atayıp, alan değerleri ile oynamak son derece anlamsız geldi. Bu nedenle bir yapılandırıcı yazmaktan vazgeçtim. Ha bu durumda, hiç bir yapılandırıcı yazmadığım için, bu işin kontrolünü Java’ya bırakmış oldum. O benim için varsayılan bir yapılandırıcı oluşturacak ve böylece ben uygulamamda new anahtar kelimesi ile rahatça nesneler yaratabileceğim. Diğer yandan, sınıfımız içine bazı metodlarda eklenebilir. Örneğin, tüm alan değerlerini düzenlediğimizi düşünelim. Bunun için bir metod yazabiliriz. Hatta aynı isimli metodu her bir alan için ayrı ayrı uygula****** alanların bireysel olarak düzenlenmesinede imkan sağlayabiliriz diye düşünürken bu işler için metodlar(set ile başlatan metodlar) yazdığımı farkettim. Ancak toplu bir düzenleme için güzel bir metod yazılabilirdi. Böylece sınıfa aşağıdaki metodu eklemeye karar verdim. Bu metod sınıf içindeki alanların değerlerini değiştirecek.
public **** Degistir(String ad,String soyad,String telefon)
{
fAd=ad;
fSoyad=soyad;
fTelefon=telefon;
} Bu metodun tek yaptığı, parametre olarak aldığı String veri türündeki değerleri alarak, sınıf içindeki alan değerlerine atamak. Sanıyorumki sınıfımın yapısı temel olarak bu şekilde olucak. Artık bu sınıfı ve bu sınıfa ait nesneleri kullanacağım bir örnek uygulamaya ihtiyacım var. Bu uygulamada elbette bir sınıf şeklinde tasarlanacak ve mutlaka main metodu olucak. Main metodu, bir sınıf için başlangıç noktası niteliğindedir. Ama tabiki tahmin edeceğiniz gibi uygulama içerisinde sadece bir sınıfın main metodu olmalıdır. Bu bilgiler ışığında, aşağıdaki örnek sınıfı hazırladım.
public class Uygulama
{
public static **** 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 küçük uygulamada, SinifKisi sınıfından k1 isimli bir nesne tanımlıyor ve alanlarının değerlerini değiştirebiliyoruz. Uygulamayı çalıştırdığımızda aşağıdaki sonucu elde ederiz.

j24_4_5.gif


Bu noktada merak ettiğim, sınıf içindeki özel alanlara erişmek istediğimde nasıl bir sonuç alacağımdı. O nedenle kodlara aşağıdaki satırları ekledim. Burada açık bir şekilde özel alanlara, tanımlamış olduğum nesne vasıtasıyla erişmeye çalışıyordum. Bakalım derleyici ne yapacak.
System.out.println(k1.fAd+" "+k1.fSoyad+" "+k1.fTelefon); Sonuçta uygulamayı derlediğimde aşağıdaki hata mesajları ile karşılaştım. Kapsülleme gerçekleşmişti. Alanları dışarıdaki sınıflardan soyutlamıştım. Onlara sadece benim tanımladığım metodlar vasıtasıyla erişilebilecekti.


j24_4_6.gif


Aslında sınıflar ile ilgili daha pek çok kavram vardı kaynaklarımda. Örneğin, static metodlar. Bu metodlar her nesne yönelimli programlama dilinin önemli bir parçası bence. Bir static metoda ne zaman ihtiyaç duyabilirdik?
Static metodlar, tanımlandıkları sınıfın örneklendirilmiş nesnesine ihtiyaç duymadan çalışabilen metodlardır. Dolayısıyla böyle bir metodu kullanabilmek için, bu metodun tanımlandığı sınıfa ait bir nesne yaratmak zorunda değiliz. Doğrudan bu metodun tanımlandığı sınıfa ve pakete nokta notasyonlarını uygula****** bu static metodu çalıştırabiliriz. Böylece sistem kaynaklarını özellikle gereksiz nesnelerle doldurmamış oluruz. Örneğin matematiksel işlemlerin yapıldığı metodları göz önüne alalım. Bir sayı dizisindeki elemanları sıralayan bir metod varsayalım. Bu metod mutlaka ve illaki bir paket içindeki sınıf içinde yer alacaktır. Çünkü nesneye dayalı programlama dillerinde herşey nesne modeli üzerine kuruludur ve tüm üyeler sınıflar içerisinde, sınıflarda belli paketler içerisinde yer alır. Paketler ile ilgilide pek çok kaynak buldum. Açıkçası bir kahve molasındada onlar ile ilgileneceğim. Java’daki paketlerin yerleşimi aslında kitaplardaki anlatımlar tarzıyla biraz gözümü korkuttu diyebilirim. Ne demiştik bir sayı disizini sıralayan metodumuz olsun. Bu metodun tek yapacağı iş, parametre olarak aldığı dizinin elemanlarına bir sırlama algoritması uygulamak ve sonucu bir dizi olarak döndürmektir. Bu işi yapması için bir nesneyi görevlendirmek sistem kaynaklarında sadece but sıralama metodu için yer açmak anlamına gelir. Oysaki metodumuzu static olarak tanımlarsak, nesne yaratmaya gerek kalmayız. Metodumuzu ise sınıf.metod notasyonu ile rahatlıkla kullanabiliriz.
Bu düşünceler ışığında acaba küçük uygulamama bu tip bir static metodu nasıl uygulayabilirim diye düşünmeye başladım. Aklıma bir metod geldi. Örneğin SinifKisi isimli sınıfa ait nesneleri ekrana düzgün bir şekilde yazdıracak bir metodum olsaydı. Aslında bu metodu SinifKisi içine yerleştiripte çağırabilirim. Ama amaç static metodları anlamak olduğu için başka bir sınıf içine almaya karar verdim. İşte o sınıfın kodları.
public class Yazmaca
{
static **** KisiYaz(SinifKisi k)
{
System.out.println("Kişi adı "+k.getAd());
System.out.println("Kişi soyadı "+k.getSoyad());
System.out.println("Kişi telefonu "+k.getTelefon());
}
} Bir static metod tanımlama için yapılacak tek iş metodun tanımlanmasına static anahtar kelimesini eklemek. Buradaki metod parametre olarak SinifKisi sınıfı tipinden bir nesne örneği alıyor. Şimdi Uygulama.java dosyamın kodlarını aşağıdaki şekilde yeniledim.
public class Uygulama
{
public static **** 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();
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)
{
Yazmac****isiYaz(kisi);
}
}
} Uygulamadaki kodlar bir anda gözüme çok güzel göründü. Üç tane SinifKisi nesnesi yaratıp alanların değerlerini değiştirmiş ve bölyece, üç farklı SinifKisi nesnesine sahip olmuştum. Diğer yandan bu nesneleri SinifKisi tipinden bir diziye aktarmış ve bu dizi içindeki her bir elemanı bir foreach döngüsünde ele alarak, static KisiYaz metodunu çağırmıştım. Herşey çok güzel olacak gibi görünüyordu. Ama öyle olmadı. Bam diye bir hata aldım.

j24_4_7.gif


Uzunca bir süre düşündüm. Acaba yanlış bir yazımmı uyguladım diye. Ama sonra dökümanlarımda bu işi araştırmaya başladım. Kimse c# taki gibi bir foreach döngüsünden bahsetmiyordu. Acaba böyle bir döngü ifadesi yokmuydu? Ta taaaa.. Hakkatten aradım taradım dökümanlarda bunu bulamadım. Belki başka bir şekli vardı. Bu amaçla elimdeki e-book lardan O’Reilly basımı 6000 sayfalık java dökümanına baktım. Buradada foreach gibi bir döngüden bahsedilmiyordu. Sadece For döngülerini bulabildim. Arayışım bittikten sonra, madem öyle olmuyor bende normal bir for döngüsü kullanırım dedim ve kodları aşağıdaki gibi değiştirdim.
public class Uygulama
{
public static **** 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();
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)
{
Yazmac****isiYaz(kisiler);
}
}
} Şimdi oldu işte. Uygulamayı çalıştırdığımda aşağıdaki sonucu elde ettim. Static metodum olan KisiYaz’a doğrudan sınıf ismi üzerinden erişmeyi başarabilmiştim.


j24_4_8.gif


Sınıflar ile ilgili işlenecek daha pek çok kavram vardı aslında. Sınıflar arası kalıtım, çok biçimlilik gibi. Ama kahvemde tükenmişti. Bir süre dinlenmeye ve kaynaklarımı okuyarak yeni bilgiler edinmeye karar verdim. Kim bilir bir sonraki kahve molamda, hangi rüzgarlara kapılacak, hangi memleketlere liman açıcaktım. En azından artık sınıfların Java’da nasıl yazıldıklarını biliyordum. Metodların, özel alanların, static metodların, yapılandırıcıların...Ama katedilecek daha çok yol vardı. Aslında gönlümden geçen, bu uygulamda gerçekten veritabanına bağlanıp bir tablodan alanları alabilmekti. Fakat yolum çok uzun ve sabretmek lazım. Java’da veritabanlarının işlenmesini çok ama çok merak etmekle birlikte önümde bilmem gereken, Paket kavramı, applet’ler, gui’ler gibi pek çok konu var. Hadi rast gele diyelim.
 
Üst

Turkhackteam.org internet sitesi 5651 sayılı kanun’un 2. maddesinin 1. fıkrasının m) bendi ile aynı kanunun 5. maddesi kapsamında "Yer Sağlayıcı" konumundadır. İçerikler ön onay olmaksızın tamamen kullanıcılar tarafından oluşturulmaktadır. Turkhackteam.org; Yer sağlayıcı olarak, kullanıcılar tarafından oluşturulan içeriği ya da hukuka aykırı paylaşımı kontrol etmekle ya da araştırmakla yükümlü değildir. Türkhackteam saldırı timleri Türk sitelerine hiçbir zararlı faaliyette bulunmaz. Türkhackteam üyelerinin yaptığı bireysel hack faaliyetlerinden Türkhackteam sorumlu değildir. Sitelerinize Türkhackteam ismi kullanılarak hack faaliyetinde bulunulursa, site-sunucu erişim loglarından bu faaliyeti gerçekleştiren ip adresini tespit edip diğer kanıtlarla birlikte savcılığa suç duyurusunda bulununuz.