Documente online.
Zona de administrare documente. Fisierele tale
Am uitat parola x Creaza cont nou
 HomeExploreaza
upload
Upload




JAVA EĞİTİM SEMİNERLERİ -II-

Java en


JAVA EĞİTİM SEMİNERLERİ -II-

NESNEYE DAYALI PROGRAMLAMA (NDP)



Nesneye dayalı programlama, (Object Oriented Programming - OOP)- 1970'lerde gelistirilen yordamsal (procedure based) programlama tekniklerinin yerini alan bir programlama yöntemidir. NDP yordamsal programlamadan çok farklı bir düsünme tarzı gerektirir.

Geleneksel yapısal programlamada veri yapıları tasarlanır ve daha sonra veriler teorik olarak kesinlikle sonlanacak sekilde fonksiyonlar ile islenir. Bu fonksiyonlara algoritma denir. Bu nedenle orijinal Pascal'ı tasarlayan Niklaus Wirth ünlü kitabına "Algorithms + Data Structures = Programs" adını vermistir. Algoritmanın önce geldiğine dikkat ediniz, bu o zamanlar programcıların nasıl çalıstığını göstermektedir. Önce verinin nasıl isleneceğine karar verilir; daha sonra islemleri kolaylastırmak için nasıl bir yapı kullanılacağına karar verilir. NDP'da ise bu sıra değisir: veri yapıl 232e41c arı önce yerlestirilir sonra veri üzerinde islem yapan algoritmalara bakılır.

NDP ile gerçeklestirilen yazılımların denetimi, düzeltilmesi ve incelenmesi yapısal programlamaya göre çok daha kolaydır. Çünkü her nesne kendi içinde bağımsız bir bütündür. Diğer nesneler ile iliskileri mesaj göndermekten ibarettir. Her nesne kendi ile ilgili verileri kendi içinde saklar, bazı verilere dısarıdan erisime izin vermeyebilir. Ayrıca programda bir nesnenin güncellenmesi programın bütününde büyük problemlere yol açmaz.

NDP'nin bir diğer avantajı da tekrar kullanılabilirliğidir. Nesneler neredeyse kendi kendine yeten bir bütün gibidirler. Programın bir yerinde canlandırıldıktan sonra yasam sürelerince bellekte kalır ve kendilerine gelen mesajları değerlendirirler. Nesnelerin bu kadar ayrık birimler olmaları yeni bir problem çözümü için tekrar kullanılabilmelerine imkan verir. Yeni problemin nesneleri benzer eski nesnelerden miras alma kullanılarak kolayca olusturulabilir.

NDP'da en yüksek verimi elde etmek için her nesne birbirleriyle iliskili bir is kümesinden sorumlu tutulmalı. Bir nesne kendi sorumluluğunda olmayan bir isi yapmak istediğinde bu isin sorumluluğunu içeren baska bir nesneye erisebilmelidir. Bunu yapısal programlamadaki fonksiyon çağrılarının bir genellestirilmesi olarak da düsünebiliriz. Java'da bu fonksiyon çağrılarına metod çağrıları (method call) denir. NDP'de ise bu istemcilerin sunucu nesnelere mesaj göndermesi olarak adlandırılır.

Yapısal programlamadaki modüllerde olduğu gibi NDP'de de bağımsız bir nesnenin gereğinden fazla is yapması istenmez. Karmasık verileri içieren ve verileri islemek için yüzlerce fonksiyon içeren büyük nesneler yerine birkaç isi gerçeklestiren küçük nesneler yaratıldığında tasarım ve hata düzeltme safhaları basitlesecektir.

NESNELER VE SINIFLAR

NDP'de programınız belirli özellikleri ve islemleri gerçeklestirebilen nesnelerden olusmaktadır. Nesne birbiriyle iliskili durumlar ve islemler kümesidir. Genellikle bir nesneye ait bir islem gerçeklestiğinde nesneye ait durumlardan bazıları değisir. Aynı sekilde islemler de bazı durumların değerine göre davranır.

Sınıf nesnenin yapıldığı kalıp veya sablon olarak tanımlanabilir. Bir sınıfa ait bir nesne yarattığınızda o sınıfın bir örneğini yaratmıs olursunuz.

Örneğin, birbirinden çok farklı bir yığın kediyi "kedi" adı verilen soyut bir sınıfın üyelerine indirgeyerek algılarız. Kedilerin en genel özelliklerini ve davranıslarını içinde barındıran "kedi" kavramı (sınıfı) düsünüldüğünde, akla kedilerin sadece fiziksel özellikleri yada sadece davranısları gelmez, aksine bir bütün olarak hem davranıs hem de fiziksel özellikleri algılanır. Kedi denildiğinde akla hem kedilerin tüylü, kuyruklu olması gibi özellikler hem de miyavlama, tırmalama gibi özellikler gelir.

Karsımıza yeni bir kedi geldiğinde bu yeni kediyi kedi sınıfının bir örneği olarak algılarız. Kedilere ait bütün ortak özellikleri bu kediye atarız. Ancak kediyi biraz dikkatle incelersek onda her kedide olmayan farklılıklar buluruz. Artık bu kedi hakkında aklımızda sadece kedi sınıfının bir örneği olmasıne ek olarak bu farklı özellikleri de saklarız. Böylece özel bir kediyi kedi sınıfına dahil olması ve farklılıkları olarak çok az veriyle tanımlamıs oluruz.

Sınıf ile nesne arasındaki iliskiyi pasta kalıbı ile pastanın kendisi arasındaki iliskiye benzetebiliriz. Sınıf pastanın kalıbına, nesne ise pastaya karsı düser. Pastanın hamuru ise burada belleğe karsı düser. Java bu hamur hazırlama yani bellek ayrıma islemini kullanıcıdan saklama konusunda oldukça basarılıdır. Java'da bellek ayırmak için new anahtar kelimesi kullanılmaktadır.

Pasta pastam = new Pasta();

Eğer bu pasta artık kimse tarafından yenmiyorsa "garbage collector" bu pastayı yer. Yani ayrılan bellek artık kullanılmıyorsa Java (garbage collector) ayrılan bu belleği bosaltır.

NDP'nin temel özellikleri:

Miras alma (Inheritance)

Eğer bir sınıf bir taban sınıftan türetilirse yeni sınıf ebeveyn sınıfın bütün özelliklerine ve metodlarına sahiptir. Bu metodları değistirebilir veya olduğu gibi bırakabilirsiniz; ayrıca sadece çocuk sınıfta uygulanabilen yeni metodlar da tanımlayabilirsiniz.

Kümeleme (Encapsulation)

NDP'nin en temel özelliği olan kümeleme bir nesneye ait özelliklerin ve davranısların nesne için bir bütün olarak saklanması anlamına gelir.

Java'da yazılan hersey bir sınıfın içindedir. Java birçok sınıftan olusmustur. NDP mantığının getirdiği bir bir kolaylık vardır: sınıflar genellikle (Java 'da her zaman) diğer sınıflar üzerine bina edilir. Java, gerçekte, bütün diğer sınıfların türetildiği bir kozmik taban sınıfı ile gelmektedir. Bu sınıf Object olarak adlandırılmıstır. Java'da bütün sınıflar bu Object adlı sınıftan türetilmistir. Java'da bir sınıfın diğer bir sınıftan miras aldığını belirtmek için extends kelimesi kullanılır.

Geleneksel yordamsal programlamada main fonksiyonu ile en yukardaki süreçten baslarsınız. Nesneye dayalı bir sistem tasarlarken en yukarıdaki diye bir kavram yoktur, bu nedenle NDP ile yeni tanısanlar için nereden baslayacakları önemli bir sorundur. Önce sınıflar bulunur sonra her sınıfa metod eklenir.

Sınıfları tanımlarken takip edilebilecek bir yol problem analizinde isimlere bakmak, aynı sekilde metodlar da fiillere karsı düser.


Sınıflar arasındaki iliskiler

Sınıflar arasındaki en yaygın iliskiler:

Kullanmak (use)

Kapsamak (containment)

miras almak (inheritance)

A sınıfı B sınıfını kullanır eğer:

A'nın bir metodu B sınıfının bir nesnesine mesaj gönderirse veya

A'nın bir metodu B sınıfından bir nesne yaratır, alır veya döndürürse

Birbirini kullanan sınıf sayısını minimize ederek bir sınıftaki bir hatanın veya değisikliğin diğer bir sınıfı etkilememesi sağlanabilir.

Kapsama iliskisi ise kullanma iliskisinin özel bir halidir. Eğer bir A sınıfı B sınıfını kapsıyorsa A sınıfının en az bir metodu B'yi kullanmaktadır.

Miras alma iliskisi özellesmeyi ifade eder. Genel olarak, eğer bir A sınıfı B sınıfından miras alıyorsa A sınıfı B sınıfının metodlarını miras alır ve bunlara ek olarak daha fazla yeteneğe sahiptir.

Nesne Değiskenleri

Java'daki çoğu sınıflar için önce nesneler yaratılır, baslangıç durumlarıı belirlenir, sonra nesnelerle çalısılır.

Nesnelere erismek için nesne değiskenleri tanımlanır. Örneğin

Kedi kedim ;

Ancak bu satır ile kedim bir nesneye isaret etmemektedir. Bir nesne yatamak için new kelimesi kullanılmalıdır.

Kedi kedim = new Kedi();

Böylece Kedi nesnesinden bir örnek yaratılır. Artık Kedi sınıfının metodlarını kedim nesnesine uygulayabilirsiniz.

Kedi boncuk = kedim;

Satırı yazıldığında yeni bir nesne yaratılmamıs olup, boncuk kedim ile aynı nesneyi isaret etmektedir.

kedim.miyavla();

boncuk.sus();

seklinde iki satır yazıldığında kedim nesnesi önce miyavlayacak sonra da susacaktır.

Çoğu sınıfın clone adında bir metodu vardır. Bu metod bir nesenin gerçek kopyasını çıkartır. "=" isleminden farklı olarak burada nesneler birbirinden bağımsızdır, yani zamanla birbirinden ayrılırlar.

Bir nesne değiskeninin o an için hiç bir nesneyi isaret etmediğini belirtmek için null değerini kullanabilirsiniz.

kedim = null;

....

if (kedim != null) kedim.miyavla();

Java'daki nesne değiskenleri C++'daki nesne isaretçilerine benzemektedir.

Kedi kedim; // Java

Kedi* kedim;// C++

Eğer bir değiskeni kopyalarsanız iki değisken de aynı nesneyi isaret eder. C++'da da Java'dakine benzer sekilde kedi nesnesi new çağrısı olmadan yaratılamaz.

Kedi* kedim = new Kedi(); // C++

Java'da bütün nesneler yığında yasar. Eğer bir nesne baska bir nesne değiskenini içerirse bu değisken de sadece heap mesmesine bir isaretçi içerir. C++'da bir nesnenin kopyasını çıkarmak imkanı varken Java'da clone metodu kullanılmalıdır.

Örnek: Java kütüphanesinin GregorianCalender sınıfı

Java ile birlikte gelen bir Date sınıfı vardır. Date sınıfının bir örneği epoch olarak adlandırılan sabit bir noktadan milisaniyelerin sayıldığı bir duruma sahiptir. Bu sınıf tarihi "December 31, 1999" seklinde ifade etmektedir. Ancak bu verilerin yeterli olmadığı "December 31, 1999 ,23:59:59" ifadesinin daha uygun olduğuna karar verilerek Java1.1'de GregorianCalendae isimli bir sınıf eklenmistir. Gregorian takvimi dünyanın çoğu yerinde kullanılan bir takvimdir.

GregorianCalender bugun = new GregorianCalender();

satırı sunları yapar:

bugun olarak adlandırılan yeni bir GregorianCalender sınıfının örneğini yaratır.

Aynı zamanda bugun nesnesinin durumunu o anki tarih olarak atar.

Ayrıca özel bir tarih için de bu sınıftan bir nesne yaratabilirsiniz.

GregorianCalender birgun = new GregorianCalender(1999,11,31);

Bu tarih Aralık 31, 1999 'i ifade eder. Bu metod için aylar 0'dan baslamaktadır, bu nedenle 11 Aralık ayını ifade etmektedir. Ayrıca bu sınıf ile saati de verebilirsiniz.

GregorianCalender bugun = new GregorianCalender(1999,11,31,23,59,59);

Asağıda GregorianCalender sınıfının kullanıslı birkaç metodu verilmistir:

GregorianCalender()

Default olarak tanımlanmıs zaman kusağında ve yerel takvim nesnesi yaratır.

GregorianCalender(int year, int month, int date)

Verilen tarihte bir nesne yaratır.

GregorianCalender(int year, int month, int date, int hour, int minutes, int seconds)

Verilen tarih ve saatte bir Gregorian takvimi yaratır.

boolean equals(Object when)

Bu takvim nesnesi ile when nesnesini karsılastırır ve eğer aynı zamanı gösterirse true değerini geri döndürür.

boolean before(Object when)

Bu takvim nesnesi ile when nesnesini karsılastırır ve eğer bu takvim when den önce gelirse true değerini geri döndürür.

boolean after(Object when)

Bu takvim nesnesi ile when nesnesini karsılastırır ve eğer bu takvim when den sonra gelirse true değerini geri döndürür.

int get(int field)

Belirli bir değiskenin değerini geri döndürür. Bu değiskenler asağıdakilerden biri olabilir:

Calender.ERA

Calender.YEAR

Calender.MONTH

Calender.WEEK_OF_YEAR

Calender.WEEK_OF_MONTH

Calender.DATE

Calender.DAY_OF_MONTH

Calender.DAY_OF_YEAR

Calender.DAY_OF_WEEK

Calender.DAY_OF_WEEK_IN_MONTH

Calender.AM_PM

Calender.HOUR

Calender.HOUR_OF_DAY

Calender.MINUTE

Calender.SECOND

Calender.MILLISECOND

Calender.ZONE_OFFSET

Calender.DST_OFFSET

void set(int field, int value)

Belirli bir değiskenin değerini atar. Bu değiskenler get metodundakiler ile aynıdır.

void set(int year, int month, int date)

Tarih değiskenlerine yeni değer atar.

void set(int year, int month, int date, int hour, int minutes, int seconds)

Tarih ve saat değiskenlerine yeni değer atar.

void add(int field, int amount)

Veri üzerinde aritmetik islem yapar. Belirli bir değiskene amount ile belirtilen miktarı ekler. Örneğin 7 gün eklenecekse asağıdaki yazılır:

add(Calender.DATE, 7)

Değistiren ve Erisen Metodlar

GregorianCalender'ın metodlarının adlandırması çoğu nesneninkinden farklıdır. Genelde setYear, getYear gibi metod adları verilirken bu sınıf için sadece get veya set metodu ile istenilen değer parametre olarak aktarılır. Yani yıl değerini döndürmek için getYear yerine get(Calender.YEAR) gibi bir metod kullanılmaktadır. Ancak çoğu sınıfta metodlar set veya get kelimelerinden sonra büyük harfle baslayan kelimeler seklinde adlandırılır.

Bu sınıfta set ve add metodları veri üzerinde değisiklik yaptığından değistiren metod (mutator method) olarak adlandırılırken get metodu sadece veriye erisim sağladığı için erisen metod (accessor method) olarak adlandırılır.

Corejava'da gelistirilen Day sınıfı

Corejava kitabında kullanıcı için daha uygun bir sınıf olan Day sınıfı gelistirilmistir. Bu sınıfta bir nesne su sekilde yaratılabilir:

Day bugun = new Day(); // veya

Day birgun = new Day(1999, 12, 31);

Burada aylar 1'den baslamakta, aralık ayı da 12 olmaktadır. Bu sınıfı kullanmak için Java'nın bu sınıfın nerde olduğunu bilmesi gerekir. Bunun için CLASSPATH değiskeni gerektiği gibi ayarlanmalıdır.

Asağıda Day sınıfının durumunu etkileyen metodlar verilmistir:

void advance(int n)

O anki tarihe n gün ekler. Örneğin d.advance(100) d tarihini 100 gün sonrası olarak değistirir.

int getDay(), int getMonth(), int getYear()

Day nesnesinin gün, ay ve yıl değerini döndürür. Günler 1 ile 31, aylar 1 ile 12 arasında değer alabilir, yıl ise her yıl olabilir.

int weekday()

Haftanın kaçıncı günü olduğunu döndürür. 0-6 arasında değer alır ve 0 pazar gününe karsı düser.

int daysBetween(Day b)

Day sınıfının yaratılmasının en önemli sebebi bu metod. O anki Day sınıfının örneğinin tarihi ile b nesnesinin tarihi arasındaki gün sayısını hesaplar.

Asağıda doğumgününden itibaren bugune kadar kaç gün geçtiğini hesaplayan basit bir program kodu verilmistir:

import corejava.*;

public class YasananGun

}

Örnek: Calendar sınıfı

Komut satırında ay ve yıl girildiğinde ekrana o ay için takvimi getiren program kodu asağıda verilmistir.

import corejava.*;

public class Calendar

else

Day d = new Day(y, m, 1); // start date of the month

System.out.println(m + " " + y);

System.out.println("Sun Mon Tue Wed Thu Fri Sat");

for( int i = 0; i < d.weekday(); i++ )

System.out.print(" ");

while (d.getMonth() == m)

if (d.weekday() != 0) System.out.println("");

}

}

Burada komut satırında Java Calendar 12 1999 girildiğinde ekrana asağıdaki yazılar gelir.


Sınıf Olusturma

Java sınıfının en basit ifadesi asağıda verilmistir.

Class SınıfınAdı

Çoğu Java programında birden fazla sınıf tanımlanır bir sınıf dğier sınıfların nesnelerini kullanır. Asağıda Employee sınıfını içeren EmployeeTest sınfı örneği verilmistir.

Örnek: EmployeeTest sınıfı

import java.util.*;

import corejava.*;

public class EmployeeTest

}

class Employee

public void print()

public void raiseSalary(double byPercent)

public int hireYear()

private String name;

private double salary;

private Day hireDay;

}

Employee sınıfındaki metodları incelersek:

public Employee(String n, double s, Day d)

public void print()

public void raiseSalary(double byPercent)

public int hireYear()

Buradaki public kelimesi erisim tanımlayıcısıdır. Java'da bu çerisim tanımlayıcıları bu metodu kimlerin kullanabileceğini belirler. public kelimesi, Employee sınıfının bir örneğine erisebilen herhangi bir sınıfın herhangi bir metodu bu metodu çağırabilir anlamına gelir.

Employee sınıfındaki değiskenleri incelersek:

private String name;

private double salary;

private Day hireDay;

Buradaki private kelimesi Employee sınıfının metodları haricinde dısarıdan hiçbir programın bu değiskene erisemeyeceğini ifade eder. Genellikle sınıf içindeki değiskenler private olarak tanımlanır; sadece birbiriyle sıkı iliskide bulunan sınıflar sözkonusu olduğunda farklı bir durum olabilir.

Burada hireDay değiskeninin baska bir nesnenin örneği olduğuna dikkat ediniz. Sınıflar çoğunlukla baska sınıfların örneklerini değisken olarak içerirler.

Constructor

Employee sınıfındaki ilk metoda bakarsak:

public Employee(String n, double s, Day d)

Bu constructor metodu örneğidir. Constructor metodları sınıfın içindeki değiskenlere baslangıç durumlarını vermek o sınıftan örnek nesne yaratmak için kullanılır.

Bir sınıfı yaratmak için new kelimesi constructor ile birlikte kullanılır. Bu da nesnelerin baslangıç durumlarını mutlaka belirtmenizi gerektirir. Java'da bir sınıfın örneğini yani bir nesneyi o sınıfın değiskenlerine baslangıç değeri vermeden yaratamazsınız. Bunun sebebi baslangıç durumu yaratılmayan bir nesnenin gereksiz ve anlamsız olmasıdır.

Constructor'ların özellikleri:

Constructor ile sınıfın adı aynıdır.

Bir constructor bir veya daha fazla (hatta hiç) parametreye sahip olabilir.

Bir constructor her zaman new kelimesi ile çağrılır.

Bir constructor'un hiç bir zaman döndürdüğü değer yoktur.

Bir constructor sadece kelimesi ile çağrılabilir, değiskenlerin değerini reset etmek için var olan bir nesnenin constructor'unu çağıramazsiniz. Örneğin d.Day(1950, 1, 1) diyemezsiniz. Böyle bir durumda bu isi yapacak değistiren metodlar (örneğin reset gibi) tanımlanabilir.

Bir sınıfın birden fazla construtor'u olabilir. Bunun örneğini GregorianCalendar sınıfında ve Day sınıfında zaten görmüstünüz.

Burda dikkat edilmesi gereken diğer bir husus metodların içinde kullanılan yerel değiskenlerin sınıfın değiskenleri ile aynı adı tasımamasıdır; aksi halde yerel değisken sınıfın değiskeninin önüne geçer.

Employee sınıfının metodları incelendiğinde sınıfın değiskenlerine doğrudan erisim olduğu görülür. Örneğin,

public void raiseSalary(double byPercent)

metodunda salary, Employee sınıfının bir değiskenidir. Bu metod salary değiskeninin değerini değistirmektedir, geriye bir değer döndürmemektedir.

ahmet.raiseSalary(5);

Çağrısı ahmet'in maasını %5 arttırır.

public int hireYear()

Metodu ise geriye bir değer döndürmektedir.

Çoğu sınıfta private veri değiskenleri sadece islemleri gerçeklestirenleri ilgilendirir. Eğer bir sınıfın kullanıcısı bir değiskene değer atamak ve değiskenin değerini okumak istiyorsa sınıfı gerçeklestirenlerin tanımlaması gerekenler:

Bir private veri değiskeni

Bir public değiskene erisim metodu

Bir public değiskeni değistiren metod

Bu, sadece bir tane public veri değiskeni tanımlamaktan daha yorucu bir islem olmasına rağmen bir çok avantajı vardır:

Sınıfın içindeki yapı değistirilirken bu sınıfın islemleri dısında hiç bir propgram kodu etkilenmez.

Basitçe bir değiskeni değistiren bir kod hata kontrolü yapamazken, değistiren metodlar hata kontrolü yapabilir

Dikkat edilmesi gereken diğer bir konu da değistirilebilen nesnelere referansları geri döndüren erisen metodların yazılmaması. Örneğin:

class Employee

public Day getHireDay()

private String name;

private double salary;

private Day hireDay;

Bu encapsulation özelliğini bozar. Asağıdaki kodun yazıldığını düsünün:

Employee ahmet= . . . ;

Day d = ahmet.getHireDay();

d.advance(10);

Hem d hem de ahmet.hireDay aynı nesneye isaret eder. d 'yi değisince otomatikman employee nesnesinin durumu da değisir. Day nesnesi değisebilir olduğundan ve advance değitiren metod olduğundan d'nin değismesi ile birlikte ahmet.hireDay nesnesi de değisir. Bu ise dısarıdan bir nesnenin durumunun değistirilmesi demek bu encapsulation'a aykırıdır.

Çözüm ise erisen metoda hireDay değiskenini geri dödürmeden önce bir kopyasının clone metodu ile alınmasıdır.

class Employee

Private verilere metod ile erisim

İki tarihi karsılastıran asağıdaki compare metodunu inceleyelim.

class Day

}

Bir çağrıya örnek:

if ( hireday.equals(d)) . . .

Private metodlar

Public veriler tehlikeli olduğu için metodlar da değiskenler gibi private olabilir. Bu metodlar sadece o sınıftaki diğer metodlar tarafından çağrılabilir. Böyle metodların kullanımı özellikle programcının islemleri parçalaması ve bu parçaların bir kısmının genel kullanım için uygun olmaması sonucu olusur. Bu metodlar sınıf dısında kullanılmazlar.

Java'da bir metodu private yapmak için public kelimesi yerine private kelimesinin yazılması yeterlidir.

Sınıf kullanıcısı ile ilgisi olmayan ve sınıfın uygulaması değistirilince desteklenmeyecek metodları private tanımlayın.

Static metodlar

Değiskenleri ve netodları static tanımlayabilirsiniz. Static değiskenler sınıfın durumu değisse bile değismeyen özelliklerdir. Benzer sekilde static metodlar sınıfın hiç bir değiskeni (davranısı) üzerinde islem yapmaz. Bu demektir ki, static metodları sınıfını bir örneğini yaratmadan kullanabilirsiniz.

Örneğin Java'nın Math sınıfının bütün metodları static olarak tanımlanmıstır.

Double x = Math.pow(3,0.1);

Bir sınıfın sırasıyla bir static metodu ve bir static değiskeni su formda çağrılır

SınıfAdı.StatikMetod(parametreler);

SınıfAdı.StatikDeğiskenAdı;

Bir diğer örnek olarak

Public static void main(String[] args)

verilebilir. main static olarak tanımlandığından onu çağırmak için o sınıftan bir örneği yaratmanız gerekmemektedir. Java yorumlayıcısı main metodunu o sınıfın bir örneği yaratılmadan otomatikman çalıstırmaktadır. Birçok main metodunun kendi sınıfının bir örneğini yarattığına dikkat ediniz.

Örnek: RandomIntGenerator

Bu sınıf Corejava'da bulunmakta ve Java'nın rastgele sayı üreten java.lang.Math.random() metodu yerine gelistirilmistir.

RandomIntGenerator k = new Ran.(10,20,30);

package corejava;

public class RandomIntGenerator

/**

* Used to return a random integer in the range constructed

*/

public int draw()

/**

* test stub for the class

*/

public static void main(String[] args)

private static double nextRandom()

private static final int BUFFER_SIZE = 101;

private static double[] buffer

= new double[BUFFER_SIZE];

static

private int low;

private int high;

}

Sınıfın çalısması su sekildedir:

Java'da bulunan rastgele tamsayı üretecini kullanarak küçük bir dizi olusturur. Dizinin kendisi ve boyu private static final kelimeleri ile sabit olarak tanımlanmıstır. Böylece bu sınıfın her örneği bu bilgiyi paylasabilir.

Belirlenen aralıkta rastgele sayıyı çizmek için draw adında bir public metodu var. Bu metodu kullanmak için RandomIntGenerator sınıfının bir örneğini yaratmanız gerekir.

Draw metodu aslında nextRandom olarak adlandırılan bir satic metod kullanmaktadır. Bu metod Donald E. Knuth''un Semi-Numerical Algorithms sf. 32 'deki algoritmasını uygulamaktadır. Bu metod Java'nın standart rastgele sayı üretecini 2 kez kullanmaktadır: birincisinde dizinin kaçıncı elemenı olduğunu belirlemek için, ikincisi ise sayının değerini belirlemek için. Bütün RandomIntGenerator sınıfının örnekleri bu islemleri içereceğinden bu metod static olarak tanımlanmıstır.

Burada static baslangıç atama bloğu yapısı kullanılmıstır. Bu blok yapısı, sınıfın static üyelerinin baslangıç durumu atamalarının yapılamadığı veya zor olacağı zaman kullanılır. Örneğin burada RandomIntGenerator sınıfı nextRandom metodunu ilk kez çağırmadan önce diziye baslangıç değeri atanmalıdır. Bunun için bir döngü olusturulmalı, döngü yapısı da basit olmadığından static baslangıç atama bloğu kullanılmıstır. Bu blok static kelimesi ile baslar arasında yazılır. Java, herhangi bir metodu çağırmadan bir kez bu static bloğu içindekileri gerçeklestirir. Bu bloklarda sadece static olarak tanımlanmıs verilere erisilebilir. Programınızda istediğiniz sayıda static baslangıç atama blokları kullanabilirsiniz, Java yukarıdan asağıya doğru bunları çalıstırır.

Sınıfın constructor 'ı sayıların sınırını belirlemektedir.

Overloading

Aynı isme fakat farklı parametrelere sahip birden fazla metodun olmasına "overloading" denir. Örnek olarak Day sınıfındaki

Day() ve

Day(int year, int month, int day)

Constructor'ları verilebilir. Java derleyicisi, parametrelerin farklı olmasından faydalanarak ilgili parametrelere sahip ilgili metodu bulur ve çağırır.

Sınıf değiskenine baslangıç değerinin atanması

Sınıf değiskenlerine baslangıç değeri atanmadıysa Java kendiliğinden 0, null veya false değeri atar. Ancak bu iyi bir programlama özelliği değildir, durumlara baslangıç değerlerinin atanması her zaman faydalıdır.

Eğer tüm constructor'ların belirli bir sınıf değiskenine aynı değeri atamaları gerekirse sınıf içindeki değiskene değer atamaları yeterlidir. Örneğin:

class Customer

Bu, tüm constructor'lar aynı değiskene aynı değeri atayacaksa çok kullanıslı bir yöntemdir.

Eğer sınıfınızı tanımlarken constructor kullanmazsanız Java default constructor tanımlar ve tüm değiskenleri sıfırlar.

this nesne isaretçisi

Bir metodda this kelimesi o metodun bulunduğu nesneyi ifade eder. Örneğin çoğu Java sınıfının ekrana yazdırmak için toString metodu vardır. Date sınıfını ele alalım. Bir tarih değiskeninde saklı o anki tarih bilgisini yazdırmak için this.toString() yeterlidir. Bu özellikle hata düzeltmede çok kullanılır.

this kelimesini baska bir anlamı daha vardır, o da bir constructor'ın ilk satırında this(.) seklinde bir ifade varsa o constructor aynı sınıfın bir baska constructor'ını çağırır. Örneğin,

class Customer

private Customer ( String n, int a)

}

finalize() metodu

Java kullanılmayan belleği otomatikman silmektedir. Bazı nesneler bellek dısında bazı özkaynaklar üzerinde islem yapabilir, bu durumda Java finalize metodunu kullanmanıza izin verir. Bu metod garbage collector belleği bosaltmadan önce çağrılır.

Örnek: CardDeck sınıfı

Bu program basit bir kart oyunudur. Program biri kendisi için biri sizin için. Olmak üzere iki kart seçer, büyük olan kazanır. CardDeck sınıfı Card sınıfını kullanmaktadır.

Bir kartın 1- 13'e kadar sayısal değeri ve 1-4 arasında türünü ifade etmek için tür değeri vardır. Asağıda Card sınıfı verilmistir.

public final class Card

public int getValue()

public int getSuit()

public int rank()

public String toString()

private int value;

private int suit;

}

Card'ın constructor'ının sayısal değeri ve türü olmak üzere iki tamsayı parametresi vardır. Asağıda CardDeck sınıfı görülmektedir.

import corejava.*;

public class CardDeck

public void fill()

public void shuffle()

}

public final Card draw()

public static void main(String[] args)

else

System.out.println("I win");

}

System.out.println

("Your wins: " + wins + " My wins: " + (rounds - wins));

}

private Card[] deck;

private int cards;

}

CardDeck sınıfının cards değiskeni kart sayısını vermektedir. Baslangıçta 52 kart vardır, kart çektikçe sayı azalacaktır.

CardDeck'in constructor'ı card nesnesinin dizisine baslangıç değeri atamaktadır. Dizi yaratıldıktan sonra fill metodu ile 52 kart olusturulur.

En son gelen kartın rastgele seçimi shuffle metodu ile gerçeklestirilir, sonra da seçilen kart ile bu kart yer değistirir.

Paketler

Java, sınıfları paket olarak adlandırılan gruplara toplamanıza imkan verir. Standart Java kütüphanesi java.lang, java.util, java.net vb. bir çok paketten olusur. Bu paketler hiyerarsik paketlerdir. Bütün Java paketleri java paket hiyerarsisinin içindedir.

Paket yazarken kaynak kodunun en üst kısmına paketin adını yazmalısınız. Örneğin GregorianCalendar sınıfına bakarsanız açıklamalardan sonraki ilk satırda su ifadeyi görürsünüz.

package java.util;

Bu GregorianCalendar.java'ın java.util paketinin bir parçası olduğunu ifade eder. Eğer kaynak dosyanızın paket tanımı yoksa Java onu default paketine ekler.

Paketleri kullanmak

Paketleri Java programlarında iki sekilde kullanabilirsibniz. Birincisi paketin tam adını yazarak, örneğin corejava.Console.readInteger() . Bu çok yorucu ve gereksizdir. İkinci yöntem ise import kelimesinin kullanımıdır. Bu kelime ile belirli bir sınfı veya genel olarak paketi kullanabilirsiniz. import kelimesini kaynak kod o paketi kullanmadan önce yazmalısınız.

import java.util.*; // java.util paketindeki bütün sınıflara erisim sağlar.

* isaretini o bir paket için kullanabilirsiniz, fakat java.* deyip java'nın altındaki bütün paketlere erisemezsiniz.

Derleyicinin paketleri yerlestirmesi

Bütün paket, paket adı ile aynı ada sahip bir dizinin altında olmalıdır. Örneğin java.util paketi java\util dizininin altındadır.

Bu dizinler kökün altında olabileceği gibi CLASSPATH ile tanımlanan dizinin altında da bulunabilirler. Örneğin,

CLASSPATH = c:\jdk\lib; c:\CoreJavaBook;.;

olarak tanımlansın ve programda su satırlar yazsın:

import java.util.*;

import corejava.*;

Java derleyicisi Console sınıfını bulmak için su dizinlere bakar:

C:\jdk\lib\console.class

C:\jdk\lib\corejava\console.class

C:\jdk\lib\java\util\console.class

C:\CoreJavaBook\console.class

C:\CoreJavaBook\java\util\console.class

C:\CoreJavaBook\corejava\console.class

.\console.class

.\corejava\console.class

.\java\util\console.class

Aslında java.util paketine bakarsanız bunun bulunmadığını fakat onun yerine classes.zip seklinde bir dosyada ziplenmis olarak durduğunu görürsünüz. Siz de tanımladığınız paketi zip dosyası olarak koyabilirsiniz.

Java her zaman java.lang paketini çağırdığından bu paketi tanımlamaya veya import kelimesi ile belirtmeye gerek yoktur.

Eğer bir sınıfı, metodu veya değiskeni public veya private olarak tanımlamazsanız aynı paketteki tüm sınıflar tarafından buna erisilebilir. Özellikle metodlar için mutlaka private yada public tanımı yapılmalıdır.

Sınıf tasarlarken dikkat edilecek bazı husular:

Her zaman veriyi private olarak tanımlayın .

Her zaman veriye ilk değeri atayın.

Bir sınıfta çok fazla basit tip kullanmayın. Örneğin

private String street;

private String city;

private String state;

yerine Address adında yeni bir sınıf yaratın.

Bütün değiskenler için erisen veya değistiren metod tanımlamak gerekmez.

Sınıf tanımlamaları için standart bir form kullanın, sınıfların içeriğini belirli bir sırada ve düzende yazın.

Çok fazla is yapan sınıfları bir kaç sınıfa bölün.

Sınıf ve metodları yaptıkları isi belirtecek sekilde adlandırın.


Document Info


Accesari: 2283
Apreciat: hand-up

Comenteaza documentul:

Nu esti inregistrat
Trebuie sa fii utilizator inregistrat pentru a putea comenta


Creaza cont nou

A fost util?

Daca documentul a fost util si crezi ca merita
sa adaugi un link catre el la tine in site


in pagina web a site-ului tau.




eCoduri.com - coduri postale, contabile, CAEN sau bancare

Politica de confidentialitate | Termenii si conditii de utilizare




Copyright © Contact (SCRIGROUP Int. 2024 )