NESNEYE DAYALI PROGRAMLAMA Ders 1 Java Nedir? Java ™ platformu , ağ(network) ‘nın önemi hesaba katılarak ve aynı yazılımın birçok değişik bilgisayar ortamında veya değişik tür makinalarda çalışması fikri ile geliştirilmiş yeni bir teknolojidir. Java teknolojisi kullanılarak aynı uygulamayı değişik ortamlarda çalıştırabiliriz – örneğin Pc lerde , Macintosh bilgisayarlarda , hatta cep telefonlarında . Java yı hem programlama dili , hemde bir ortam olarak düşenebiliriz . Programlama dili olarak , açık , nesneye yönelik (object-oriented) , güvenli , sağlam , internet için elverişli bir teknoloji diyebiliriz . Ortam olarak da işletim sistemi , veri tabanı (database) , ve orta katman (middleware) teknolojileri bulmak mümkündür. Gerek Java , gerekse Java’ya bağlı alt teknolojiler , VB veya Borland Delphi gibi sadece belli bir firma tarafından geliştirilmiş olan başlı başına ürünler değillerdir . Java ve Java’ya bağlı alt teknolojiler , Sun Microsystems tarafından verilmiş açıklamalardan oluşmaktadır . Bu açıklamalara sadık kalan her yazılım fırması JVM(Java Virtual Machine = Java) veya Java’ya bağlı alt teknolojiler yazabilir/gerçekleştirebilir. Eğer bu açıklamalara (specifications) sadık kalmayıp , standart dışı bir JVM veya Java’ya bağlı alt teknoloji yazmaya/gerçekleştirmeye kalkarsanız hukuki bir suç işlemiş olursunuz(Microsoft firmasının yaptığı gibi). Şu anda en yaygın kullanılan JVM ler , IBM’in ve Sun Microsystems ın üretmiş olduklarıdır, ayrıca HP , Apple ve daha bir çok firmanın üretmiş oldukları JVM ler bulunmaktadır Java ile ne yapılabilir? Java Programlama dili ile projelerimizi diğer programlama dillerine göre daha kolay ve sağlıklı bir şekilde yapmanız mümkündür . Kısaca göz atacak olursak , Java ile ; · GUI (graphical user interface , grafiksel kullanıcı ara yüzü) uygulamaları , appletler. · Distributed components (ör . EJB, RMI, CORBA). · Servlet , Jsp (web tabanlı uygulamalar). · Veri tabanlarına erişim ile alakalı uygulamalar. · Cep telefonları , Smart kart lar için uygulamalar . · Ve daha niceleri …. için uygulamalar yazmamız mümkünkür. Java nasıl çalışır? Java uygulamaları JVM (Java Virtual Machine) tarafından yorumlanır. JVM , işletim sisteminin en tepesinde bulunur.Bu sayade yazımış olan Java uygulamaları değişik işletim sistemlerinde , herhangi bir değişiklik yapmadan çalışabilir, Java nın felsefesi olan “bir kere yaz heryerde çalıştır” sözü gerçekleştirilmiştir. Şekil 1 Aşağıdaki şekillerde , javanın kaynak kodundan, çalışmasına kadar olan evreleri gösterilmektedir. Derleme anı (Compile Time) Çalışma anı ( Run-time) Şekil 2 Byte koduna çevrilen kaynak kod , JVM tarafından yorumlanır ve uygulama çalıştırılmış olur. Java uygulaması örneği Ufak bir Java uygulaması örneği , bu örneği birazdan detaylı olarak inceliyeceğiz. public class Selam { public static void main(String args[]) { System.out.println("Selamlar !"); } } Şekil 3 Yazılan java kaynak kodlarımız ilk önce derlenir daha sonra ise çalıştırırız. Java kaynak kodunda belirttiğimiz her sınıf (class) için fiziksel olarak bir class dosyası oluşturulur. Gelişim Evreleri 1995 Java Teknolojisinin ilk çıkış yılı ; ilk olarak applet teknolojisinin dikkat çektiği seneler. 1996 Java Development Kit (JDK) v1.0 çıkartıldı. Temel seviyeli işlevleri içeren bir versiyon (ör. soket programlama, dosya I/O, GUI) 1997 JDK 1.1 çıkartıldı. Bu sürümde Java GUI , veritabanı erişimi için JDBC , dağınık objeler için RMI ve daha birçok yeni gelişmeler eklendi . 1998 JDK 1.2 çıkartıldı . JFC/Swing yayınlandı- aynı sene içersinde 500,000+ download gerçekleştirildi. 1999 Java teknolojisi J2SE, J2EE ve J2ME olarak 3’e bölündü . Java HotSpot (performans arttırıcı) yayınlandı . JavaServer Pages (JSP) teknolojisi yayınlandı. J2EE platform’u yayınlandı . Linux üzerinde J2SE platformu yayınlandı . 2000 JDK v1.3 çıkartıldı . Java APIs for XML teknolojisi yayınlandı . Javanın başarılı olmasındaki sebebler 1. Çok güzel bir programlama dili olması a. C/C++ da olduğu gibi hafıza problemlerinin olmaması . b. Nesneye yönelik (Object - Oriented) olması . c. C/C++/VB dillerinin aksine dinamik olması . d. Güvenli . e. Internet uygulamarı için elverişli . 2. Platform bağımsız olması : bir kere yaz her yerde çalıştır Çöp toplayıcı (Garbage Collector ) Çöp toplayıcı devamlı olarak takip halindedir.Bir programın çalışma durumunda , ortaya çıkan ve sonradan kullanılmayan(gereksiz ) objeleri bulur ve onları yok eder. Böylece hafıza yönetiminin (memory management) yükü kodu yazan kişiden javaya geçmiş olur. Diğer dillerde , örneğin C++ da , oluşturulan objelerin yok edilme sorumluluğu kodu yazan kişiye aittir . Çöp toplayıcının ne zaman ortaya çıkıp temizleme yapamayacağı belli olmaz.Eğer hafızada java için ayrılan kısım dolmaya başlamış ise çöp toplayıcısı devreye girerek kullanılmayan objeleri hafızadan siler. Eğer hafızada kullanılmayan objeler var ama hafızasa daha çok boş yer varsa çöp toplayıcısı devreye sokulmaz. Çöp toplayıcısı(garbage collector) JVM in yazılışına (implementation) göre değişkenlikler gösterebilir. Javada yorum satırı Java kaynak kodunun içersine istediğiniz yorumları yazabilmeniz için belli yol izleminiz gerekmektedir.Örneklerimizde yorum satırılarını çokca kulalladığım için bunu en başta açıklama ihtiyacını duydum. Javada yorum satırlarını belirtme iki şekilde mümkün olur : /* yorum */ , slash - yildizdan , diğer yildizslash arasına kadar istediğiniz yorumu yazabilirsiniz . Uzun satırlı yorumlarda bu yöntemi kullanabilirsiniz. // yorum , tek satırlık yorum yapmak için idealdir. Kısa yorumlarınız için bu yöntemi kullanabilirsiniz Java bir obje dilidir Her programlama dilinin kendine has veri yönetim şekli bulunur . Bir programın çalışması süresince objeler oluşturulur . Burada ki soru bizim objelere direk olarak mi kullandiğimiz yoksa onlara dolaylı bir şekilde mi bağlantı sağlayıp kullandığımızdir. Java da herşeye obje olarak davranırız. Herseyin obje olmasına rağmen objeleri yönetmek için “ referanslar” kullaniriz . Örnek : Diyelim ki elimizde bir televizyon(obje olarak düşünün) ,ve bu televizyona ait birde kumanda(referans) olduğunu düşünelim. Sesi alçalmak istediğimizde veya kanalı değiştirmek isteğimizde elimizdeki uzaktan kumandayı televizyonu yönetmek için kullanılız. Bu uzaktan kumandayı (referans) alıp odanın içinde gezebiliriz , sonuçda uzaktan kumanda(referans) televizyona baglıdır ama televizyonun yeri sabittir. Elimizde uzaktan kumanda (referans)olmasi , televizyonumuzun (obje) olucağı anlamina gelmez . Uzaktan kumandamiz (referans) da tek başına hayatı sürdürebilir. String kumanda; // kumanda referansı şu an için String bir objeye bağlı değil. Burada yapılan olay sadece referans oluşturmaktır . Eğer bu referansa mesajlar göndermeye kalkışırsak ne olur ? tabii ki hata mesajı ile karşılasırız , sebebi ise bu referansın herhangi bir objeye bağlı olmamasıdır. Peki referansımızı bir obje bağlıyalım : örnek-1 örnek-2 String kumanda= new String("Selamlar") ; String kumanda="Selamlar" ; Yukarıda yaptığımızın, referanslara obje bağlama örneklerinin birbirlerinden farkları yoktur. Sonuçta her iki gösterimde referanslara objeleri bağlar.Ama javada String objelerinin özel bir yeri vardır , String objeleri çok kullanılan objeler oldukları için örnek-2 deki gösterimde doğru ve bir nevi kısa yoldur Sınıf (Class) nedir ? Obje nedir ? Sınıf ve Obje i bir benzetme ile açıklayalım. Sabun fabrikasında yeni bir sabun dizaynı üzerinde çalıştınız ve ortaya bir kalıp çıkartdınız artik üretim aşamasına geçmek istiyorsunuz. Bu kalıpda sabun un hangi boyutlarda olucağı, hangi renkde olucağı , nasil kokucaği vb.. gibi bilgiler hepsi sizin tarafınızdan tespit edilmişdir. Üretim aşamasına geçildiğinde hep aynı sabun kalıbını kullanarak yeni sabunlar üretmeniz mümkün olacaktır , sabun kalıbının tasarımı bir kere yapıldı ama o kalıpdan yola çıkarak n tane sabun objesi üretmeniz mümkün olmaktadır. Bu örnekden yola çıkarak , kalıp'ı class a , sabunları ise objelere benzetebiliriz. Java da depolanan (Storage)veriler nerede durmakda Depo, toplam 6 alandan oluşur , Bu 6 alanı açıklarsak : Register : En hızlı alan burasıdır .Bu alan Cpu nun içinde bulunur , ve derleyicinin(compiler) ihtiyaclarına gore pay edilir . Bu alanda bizim direk bir kontrolumuz yoktur. Stack : Bulunduğu nokta RAM (random-access memory) dır . Bu alanda bulunan “stack pointer” ına direk olarak Cpu dan destek vardır . Stack pointer aşağıya inince yeni bir hafiza alanı oluşturur , yukarı kalkınca ise hafızayı alanını bırakır . Java derleyicisi programı oluşturmadan evvel , stack üzerinde oluşturulacak olan verilerin boyutlarını ve ömürlerini (lifetime) bilmek zorundadır çünkü stack pointer i aşağı ve yukarı hareket ettirecek olan kodu oluşturması gerekmektedir . Stack üzerinde referansların kendileri bulunur. Heap : Burası genel amaçlı bir hafıza havuzudur . Stack alanının tersine , derleyici burada ne kadar hafıza pay edileceğini bilmek zorunda değildir .Bu büyük bir rahatlık getirmektedir çünkü ne zaman bir obje yaratmak istersek sadece new anahtar kelimesini kullanarak bu alanda bir yer kendimize tahsis etmiş oluruz .Bu kadar rahatlığın karşılığında ise ödenmesi gereken fatura hızdır . Heap de yer ayırmak icin harcanan zaman , stack alanında yer ayırmaktan daha fazladır.Heap de objelerin kendisi durur. Statik Alan : Bu alanda RAM de bulunur.Statik alanda yer alan veriler , programın çalışması süresince orada yaşarlar . Tüm objeler bu statik verileri görebilirler , ortak bir alan gibi düşünebiliriz . Veriyi statik yapmak icin static kelimesini değişkenin önüne getirmemiz yeterli olur . Objelerin kendileri bu alanda yer almazlar. Sabit Bellek : Programın içindeki sabit değerlerin içinde bulundukları yerdir . Tercihen ROM(read only memory) da da yer alabilirler . Non-RAM Belek : Bazı durumlarda uyguların içersinde oluşturduğumuz objelerin,uygulama sonlandıktan sonra bile varlıklarını sürdürmelerini isteriz. 1 ) Akışkan Objeler (streamed objects) : Bu objeler , genellikle ağ(network) üzerindeki başka bir makinaya gönderilmek üzere byte akıntılarına dönüştürülürler. 2 ) Kalıcı Objeler ( persistent objects) : Bu objeler kendi durumlarını(state) saklarlar ve diskimizde saklanırlar . Kendi durumlarını saklamaktan kasıt ise özelliklerinin(attribute) değerlerinin korunmasıdır. İlkel Tipler Java da bulunan özel bir grup daha vardır . Bu grup a ilkel (primitive) tipler denir. Bu tipleri uygulama yazarken çok kez kullanırız. Bu sebepten bu ilkel tipleri heap alanında new anahtar kelimesi ile oluşturmak pek de avantajlı olmamaktadır . Bunun yerine bu ilkel tiplerin stack alanında saklanması çok iyi performans vermektedir. Yanlız buradaki espiri , her ilkel değişken bir referans değildir , bu ilkel tipler değerlerini kendi üzerlerinde taşırlar. Bu ilkel tiplerin birer adet sarmalıyıcı(wrapper) class ları bulunur . Bunun anlamı eğer heap alanında ilkel olmayan (nonprimitive) bir tip oluşturmak istiyorsanız o zaman bu sarmalıyıcı(wrapper) class kullanabilirsiniz. char c = 'x' ; // ilkel tip Character C = new Character(c); // sarmalıyıcı class Geçerlilik Alan(Scope) Bir çok programlama dilinde değişkenlerin geçerlilik alanı kavramı bulunur.Java , C ve C++ dillerindeki değişkenlerin geçerlilik alanlarını örnekler ile göstermeye çalışalım. Bir değişken sadece kendi geçerlilik alanının sonunda kadar geçerli olur . Aşağıdaki örnek C ve C++ için doğru , Java programlama dili için yanlış bir ifadedir. Örneğimizde görüldüğü üzere dış alan , iç alanı kapsamaktadır. Java dilinde , dış alanda bir değişken belirtilmiş ise bu değişken iç alanda da hayatını sürdürmeye devam eder. Geçerlilik Alanı (Scope of Objects) Java dilinde objelerinin ömürleri , ilkel tiplere göre daha değişiktir . Yukarıdaki gibi bir örnekde , if koşuluna kesinlikle girilecektir , if koşuluna girdiği anda String objesini heap alanında yaratacaktır , bu yeni yaratılan String objemizi , "s" String tipindeki referansımızla kontrol etmekteyiz.Peki if koşulundan çıkıltığında neler olucaktır ? Geçerlilik alanını sona erdiğinden "s" referansımız artık kullanılamıyacak hale gelecektir ama ya heap deki String objesine neler olacaktır ? Buradaki cevap basittir , Çöp toplayıcı(Garbage Collector) devreye girdiği an heap alanındaki bu erişilemez ve çöp haline gelmiş olan String objesini hafızadan silecektir. Yukarıda bahsettiğimiz hikaye C++ dilinde büyük bi r sorundur, çünkü C++ dilinde oluşturulan her objeyi yok etme sorumluluğu yine kodu yazan kişiye aittir. Eğer kodu yazan kişi oluşturmuş olduğu herhangi bir objeyi daha sonradan yok etmeyi unutursa hafıza kaçakları oluşmaya başlayacaktır. Yeni sınıf oluşturma Java da kendimize özgü nasıl bir sınıf oluşturabiliriz sorusuna yanıt olarak aşağıdaki örnek iyi bir cevap olmayacaktır. Gayet ilkel ve gereksiz bir sınıf (class) oluşturduk ,hiç bir fonksiyonelitesi olmayan bir sınıf . Bu sınıfımızı ilerleyen safhalarda geliştireceğiz . Alanlar ve Metodlar (Fields and Method) Bir sınıf(class) tanımladığımız zaman , bu sınıfımızın üzerinde iki sey yapabiliriz. 1 ) Alanları tanımlarız . Bunlar ilkel tipler (primitive) olabilirler veya bir obje ile iletişim kurabilmemiz için o obje tipindeki bir referans olabilirler. Örnek 1: Eğer alanlara , onlar ilk oluştuğunda , ilk değerlerini vermek istiyorsak ; Örnek 2: Bu alanları(field) kullanmadan evvel onların ilk değerlerini almış (initialize)olmaları gerekmektedir.Peki ör-1 de biz herhangi bir ilk değer verme işlemi yapmadık ve java bize bu konuda kızmadı , neden ? Bu sorunun cevabı aşağıdaki tabloda yatıyor .Eğer bir sınıfın(Class) alanlarını oluşturup onlara ilk değerlerini vermez isek -ki ör-1 de yaptığımız tamamen böyle bir harekettir o zaman java bu sınıf alanlarına kendi mevcut-varsayılan (default) ilk değerlerini verir , bu mevcut değerleri yukarıdaki tablodan inceliyebilirsiniz . 2 ) Metodlar , objelerimizin işe yarar hareketler yapmasına olanak veren kısımlar diye bir giriş yapsam sanırım yanlış olmaz . İşe yarar hareketlerden demek istediğim, objemizin canlı olması , yani ona bir soru sorduğumda bana cevap verebilmesi veya belli koşullarda kendisine önceden verilmiş kriterlere göre karar vermesini sağlamak.Metodları bu kadar cok abartı anlattıktan sonra biraz daha derinlemesine inceliyelim istersen. Metod iskeleti Şimdi bir önceki slayttaki metod iskeletinde tanımlanmış olan kısımları teker teker açıklıyalım dönüşTipi = Metodların iki şansı vardır , ya bir değer döndürürler veya hiçbirşey döndürmezler.Değerden kasıt ettiğim metodlar ya bir ilkel tip döndürebilirler (int , double,boolean) veya bir obje döndürebilirler (String , Double , Integer , YeniBirSinif). Eğer bir metod hiçbirsey döndürmüyorsa o zaman void ekini metodun başına yerleştiririz . metodunİsmi = Javanın kendisine ait olan kelimeler(if , else , import , class , return..vb) ve türkçe krakterler hariçinde istediğiniz ismi kullanabilirsiniz ama metodlar bir eylem içerdikleri için , metod isimlerininde bir eylemi belirtmesi tercih edilir örneğin : sayiSirala() , enBuyukSayiBul(),sqlCalistir() gibi . Burada dikkat edecek olursanız , metod isimlerinin ilk harfleri küçük sonra gelen ek kelime ise büyüktür. arguman listesi= Metod içersinde işlemler yapabilmek için gerekli olan parametreler.Bu parametreler ilkel tipte veya Obje olabilirler. metod gövdesi = Bu kısım kodu yazan kişinin yaratıcılığına bağlı olarak değişmektedir. Bu kadar açıklamadan sonra gerçek bir metod örneği verebiliriz . Met-Ör1 boyutDondur() metodunu herhangi String objesini parametre olarak alıyor ve bu String objesinin boyutunu geri döndürüyor. Metodumuzun geri döndürdüğü değer ilkel bir tip olan int . Herhangi bir değer geri döndürebilmek için return anahtar kelimesini kullanmamız gerekli . Met-Ör2 Metod-Ör2 de ise elmaHesapla() metodu int tipinde parametre alıyor , sonra yeni bir String objesi oluşturup bunu geri döndürüyor . Buradaki ilginç olabilecek olan husus , int olan bir değişkeni iki ile çarpıp sonradan + operatörü ile String in sonuna eklenmiş olması olabilir . Diğer dillerde bu işlem için belli bir çevirici fonksiyona ihtiyac duyardik , örneğin delphi de intToStr() fonksiyonunu çok kere kullandığımı hatırlarım, ama java da String bir ifadeden sonra gelen herhangi bir tipdeki değişken otomatik olarak String e çevrilir . " toplam elma sayisi = " ifadesi String bir ifadedir ve bu ifadeden sonra gelecek olan her türlü tip (ilkel veya Obje) , otomatik olarak String dönüştürülürler. Eğer javanın yardım dokumanlarından Object tipine ait bilgilere bakarsanız , her objenin hali hazırda toString() metodunun var olduğunu görürsünüz . Eğer bir Obje otomatik veya değil String objesine dönüştürülmek istenirse bu objenin toString() metodu çağrılır . Metod-Ör3 örneğimizde , hesapla() metodu iki adet parametre almaktadır ve geriye hiçbirşey döndürmüyeceğini bize açık açık void anahtar kelimesi ise söylemektedir. Bu örneğimizde dikkat etmemiz gereken ikinci nokta ise metodların içersinde tanımladığımız değişkenlerin ilk değerlerini kesinlikle ama kesinlikle bizim tarafımızdan belirtilmesi gerekmektedir. Met-Ör-3 Sınıf(Class) lara ait global değişkenlere (veya alanlarda diyebiliriz hepsi aynı anlamı taşımaktadır) ilk değerlerini vermediğimiz zaman java bu değişkenlere ilk mevcut - varolan değerleri kendi verir ,ama metod içersinde tanımlanan değişkenler için aynı durum söz konusu değil , bu sebepten dolayı toplamboyut değişkeninin tanımlanma şekli yanlıştır. Metod-Ör4 , örneğinin ana fikri void ile return anahtar kelimelerinin aynı metod içinde kullanımını göstermektir. if - else kontrol mekanizmalarını henüz görmedik ama bu örnek için kullanılmaları gerekliydi. Buradaki return parametresi metodun acilen terk edilmesi gerektigini anlatır . Met-Ör-4 İlk java programımız Ör-ilkJava1 İlk örneğimizi adım adım açıklayalım; fakat şunu hemen belirtmek gerekir ki, java büyük ve küçük harfe karşı duyarlıdır (case sensitive). public yerine PUBLIC yazarsanız hata ile karşılaşırsınız. public class Selam : Bu kısımda yeni bir sınıf oluşturuyoruz public static void main(String args[]) : Javada bir sınıfın tek başına çalışmasını istiyorsak (standalone) bu metodu yazmak zorundayız . Bu metodu sınıflar için bir başlagıç noktası olarak var sayabiliriz.Burada iki bilinmedik konuyu ele almak gereklidir, birincisi statik metodlar , ikincisi ise diziler (array). statik metodlar : statik metodları , objeye bağımlı olmayan metodlar diye tanımlıyabiliriz. Bu metodların kullanılması için objenin oluşturulmuş olması gerekmez . Ör-Normal1 Ör-Normal1 de uyariYap() metodu statik bir metod değildir . Bu yüzden bu metodun çağrıla bilmesi için TestNormal objesinin oluşturulması gerekmedir , bu kısıma dikkat lütfen . Şimdi diğer örneğimize geçelim . Ör-Statik1 Bu örneğimizde tek değişen sey uyariYap() metodunun statik olmuş olmasi değildir , bu metodun çağrılma şeklide değişmiştir. uyariYap() metodu artik TestStatik objesine bağlı bir metod değildir , yani uyariYap() metodunu çağıra bilmemiz için TestStatik classını oluşturmamız gerekmez. main() metodunda da işler aynıdır , fakat main() metodunun java da çok farklı bir yeri vardır.main() metodu java uygulamaları için bir başlangıç noktasıdır . Diziler (Arrays) : main() metodu parametre alarak String obje dizisi alır , bu String obje dizinin içersinde konsoldan java uygulamasına gönderilen parametreler bulunur . args[0] : konsoldan girilen 1. parametre değerini taşır .. args[1] : konsoldan girilen 2. parametre değerini taşır .. args[n] : konsoldan girilen n. parametre değerini taşır .. Javada diziler sıfır dan başlarlar . System.out.println("Selamlar !") : Bu komut satırı , bilgileri konsola(ekrana) basmamızı sağlar . Java nin dokümanlarına bakarsak , System sınıfınına ait static bir metod olan olan out methodunun var olduğunu görürüz. Bu yüzden System sınıfını oluşturmak zorunda degiliz (new System() gibi ). out methodu bize printStream objesi oluşturur ve printStream objesinin println() methodu ile bilgileri konsola(ekrana) bastırırız.