JAVA ve OOP (NYP) Mantığı.. (Makale)

By-CyL1nD3r

Uzman üye
1 Eyl 2008
1,485
14
BuRs4
Artık Object Oriented Programming konusunda yazılar yazmanın zamanı geldi diye düşünüyorum ve sözü daha fazla uzatmadan OOP yazı dizimizin ilk bölümüne geçiyorum:

OOP: Açılımı Object Oriented Programming (Nesneye Yönelik Programlama) 'dir. Structural (yapısal) kodlama felsefesinden farklı bir programlama tekniği olarak bilinen OOP, programlamanın bir nesne hiyerarşisi içinde, Child (Çocuk) ve Owner (Sahip) mantığıyla yapılmasını sağlar...
Sınıf-Nesne: Her zaman aynı şey zannedilen sınıf ve nesne arasındaki ince çizgiyi en basit haliyle ayırmanın vakti geldi sanırım. Sınıfı bir tanım, Nesneyi ise bir varlık olarak kabul edersek (ki teorik olarak böyledir) konuyu daha rahat açıklayabiliriz diye düşünüyorum. Gerçek hayattan örnekler vermek gerekirse; İnsan'ı bir sınıf, Taylan'ı da bir nesne olarak düşünebiliriz. Şöyle ki;
İnsan: Kulağı, burnu, ağzı, iki tane bacağı, iki kolu, iki gözü, saçları, midesi (etc. etc.) olan, yemek yiyen, koşan (etc. etc.) bir varlıktır.
Taylan: (İnsan sınıfından referans alarak) Bir İnsandır. Özel olarak Kahverengi gözleri, orta kalınlıkta kaşları, sıkı bir göbeği , kalın bacakları vardır. Yemek yer, Su içer (etc. etc.).
Elbette bu tanım pek birşey anlatmadı size. Ama daha açıklamasını ve mantalitesini anlatmadık. Yukarıda iki tanım bulunmaktadır. Bu tanımlardan İnsan, yemek yeme eyleminde bulunan, koşan bir varlık değildir. Saadece içinde global olarak insan sınıfının özelliklerini barındırır. Taylan Nesnesi (Ve aslında aynı zamanda sınıfı, kendi childları da olabileceği için) ise İnsan sınıfının bu özelliklerini fiili olarak gerçekleştirebilme yeteneğine sahiptir.. Bu gibi örnekler çoğaltılabilir. Ancak temel olarak OOP'un yaptığı işi az çok anlatmaya çalıştım (Bunun için Kobay'ımız Taylan'a teşekkürler). Şimdi sıra OOP tekniğinin ve Sınıf-Nesnelerin Delphi'deki kullanımına geldi.

Delphi'de yeni bir sınıf;
Type
TSinif = Class(TObject)
end;

şeklinde yaratılır. Buradaki TObject, Delphi'deki sınıf hiyerarşisinin en başında bulunan sınıftır. Kısaca herşey TObject'ten üretilmiştir.
TSinif = Class(TObject) ile TSinif = Class aynı işi yaparlar.

Inheritance (Kalıtım)
Sınıfların birbirlerinden türeyebildiğinden, en basitinden yaratacağımız her sınıfın en az TObject sınıfından türetildiğinden bahsetmiştik. Bu olaya OOP tekniğinde Inheritence yani Kalıtım adını veriyoruz. Bir nesneyi başka bir nesneden kalıtırken yukardaki declare mantığını kullanıyoruz;
Type
TBaskaSinif = Class(TSinif)
End;
Yukarıda yaratmış olduğumuz TSinif sınıfından TbaskaSinif adında yeni bir sınıf türetmiş olduk... Elbette bu yarattığımız sınıflar şimdilik hiçbir işe yaramıyorlar. İşe yarayabilir kılabilmek için bu sınıflara bir takım özellikler, davranışlar v.s. eklememiz gerekir. Bunlar için kullanılan ana yapı ise şudur:
Type
TSinif = Class
{degiskenler, procedure’ler}
private
{Saadece Sınıfın yaratıldığı unit tarafından kullanılabilecek değişken – prosedürler}
protected
{Kısmen sınırlandırılmış, bu sınıf üzerinden uygulama geliştierecek olanların kullanabileceği değişken - prosedürler}
public
{Heryerden kullanılabilen değişken – prosedürler}
pubhished
{Özellik method’larının yerleştirildiği alandır (Object Inspector’da görünen özellikler)}
end;

Şimdilik OOP yazı dizimizin ilk bölümünü burada sonlandırmak istiyorum... Gelecek bölümlerde artık sınıfları reel olarak yaratmaya ve kullanmaya başlayacağız elbette... Ama daha önce Method’lar, Sınıf Method’ları, Constructor – Destructor gibi sınıflar hakkında bilmeniz gereken temel birkaç bilgiyi daha size aktarmamız gerekecek...

Tekrar merhaba herkese... OOP yazı dizimize kaldığımız yerden devam ediyoruz... Bir önceki yazıda Sınıf ve Nesne kavramını birbirinden ayırmaya ve ikisi arasındaki farkı anlamaya çalışmıştık... Şimdi OOP’un teknik özelliklerinden bahsedeceğim biraz...

Öncelikle Method’lardan bahsetmeliyim diye düşünüyorum:
Method’lar:
Constructor’lar ve Destructor’lar: Constructor, nesneler yaratılırken (nesne.create gibi bir method’la. Küçük bir not: Sınıflar Yaratılmaz, declare edilir.) çağırılan methodlardır. Genelde bir nesneyi bir sınıftan referance alıp yaratırken bir tane Constructor methodun olduğunu (Create) görürüz. Ancak birden fazla Constructor methodu da yazılabilir... Örneğin bazı durumlarda değişik parametrelerle birden fazla yaratıcı method’a ihtiyacınız olabiliyor (Bu konulara ileride değineceğiz zaten). Destructor’lar ise nesneler yok edilirken (nesne.free gibi) çağırılan method’lardır. Her ikisinin de genel kullanım şekli aşağıdaki gibidir:

type
Sinif = Class
constructor create(parametre1,parametreN: ParametreTipi);
destructor free(Parametre1,parametreN: ParametreTipi);,
end;

Genel olarak constructor ve destructor’ları standart create (Parametresiz) ve free (parametresiz) olarak kullanacağız... Ama parametreye ihtiyacımızın da olabileceği ihtimaliyle parametre de yazabileceğinizi göstermek istedim... Bu arada küçük bir hatırlatma, hala bir sınıftan referance alarak gerçek bir nesne yaratmaya başlamadık...

Procedure ve Function Method’ları: Bildiğimiz procedure ve function yaratmaktan bir farkı yoktur.. Ancak özellikle almamın sebebi, bir sınıf deklarasyonu içerisindeki procedure ve function’ların o sınıfa ait birer method olduklarını da unutmamanız içindi...

type
Sinif = Class
procedure Prosedur(Parametreler: ParametreTipi);
function Fonksiyon(Parametreler: ParametreTipi): FunctionTipi;
{FunctionTipi aynı zamanda döndüreceği değerin tipi anlamına gelir}
end;

Sınıf Procedure’leri ve Function’ları: Normal procedure ve function’ların yaptığı işi yaparlar. Tek farkları Sınıf.Prosedur şeklinde direkt olarak kullanılabilirler, yani bir nesne yaratmadan... Yazılışının da normal function’lardan tek farkı başına class belirtecinin yazılmasıdır...

type
Sinif = Class
class procedure prosedur(parametreler: ParametreTipi);
class function fonksiyon(parametreler: ParametreTipi); FunctionTipi;
end

Bu seferlik de OOP bölümünün sonuna geldik.. Bir sonraki bölümde (Pembe dizi gibi oldu ama eheu) Sanal Method’lar (Virtual Method) ve Dinamik Method’lara (Dinamic method) göz atacağız.. Daha sonradan Inheritance, Polimorfizm gibi konularla OOP konusunun derinliklerine doğru uçuşa geçeceğiz...

En son sınıf methodlarına kabaca göz atmıştık... Şimdi de sınıflar ve OOP konusuna aynı biçimde devam ediyoruz... Konuları bu şekilde kabaca anlatıp, kavram olarak OOP'yi ve Sınıf-Nesne mantığını anlamanızı sağladıktan sonra gerçek sınıf deklerasyonları ve nesne hiyerarşisi konusunda uzunca örneklerimiz olacak zaten...

Statik (Static) Methodlar: Normalde yarattığımız bütün Methodlar Statiktir... Extra bir ifade gerektirmemelerine rağmen, Static parametresiyle birlikte de kullanılırlar... Yani
procedure MyProc; //ile
procedure MyProc; static; //aynı şeydir....

Sanal (Virtual) Methodlar: Aslında Polimorfizmi anlatmadan bunun ne olduğunu anlatmaya çalışmak doğru mu bilmiyorum ama girmiş olduk bir kere... Normalde bir sınıf verisi içerisinde method deklare ederken, o sınıftan türetilen sınıflar aynı isimde bir method deklare edemezler. Bunun yapılabilmesi için Polimorfizm dediğimiz teknik geliştirilmiş ve bu sayede aynı method ismine sahip, fakat farklı işleri yapabilen methodların üretilmesine izin verilmiş... Bir methodun sonuna Virtual getirilerek, o methodun bu sınıftan üretilecek alt sınıflar tarafından ezilmesine izin verilir. Virtual method'ları kullanacak sınıflar ise, bu methodu Override parametresiyle ezerek kullanabilirler;

type
TSinif = class
procedure prosedur; virtual;
end;

TYeniSinif = Class(TSinif) //Buraya dikkat edin!!!
procedure prosedur; override;
end;

TYeniSinif2 = Class(TSinif)
procedure prosedur; override;
end;
end;

Yukarıda da anlaşılacağı üzere ana sınıfa ait (TSinif) prosedur ismindeki prosedür sanal olarak yaratılıyor ve onun çocuk sınıfları tarafından (TYeniSinif ve TYeniSinif2) eziliyor... Ve her sınıf kendi sınıf deklarasyonu içerisinde onu baştan tanımlayarak prosedur içine kendi kodlarını yazabiliyor... Sanal Methodlar VMT (Virtual Method Table) denilen bir yöntem kullanırlar. VMT hızlı ancak hafıza harcayan bir yöntemidir...

Dinamik (Dynamic) Methodlar: Sanal Methodlardan tek farkı vardır; VMT değil DMT adı verilen bir mantığa dayalıdır.. Bu mantıkda da az hafıza harcanır ancak hız düşer.. Onun dışında bütün kullanım biçimleri aynıdır... VMT ve DMT tablolarını ilerleyen bölümlerde daha ayrıntılı açıklayacağım...

type
TSinif = class
procedure prosedur; dynamic;
end;

TYeniSinif = Class(TSinif)
procedure prosedur; override;
end;

TYeniSinif2 = Class(TSinif)
procedure prosedur; override;
end;
end;

Mesaj (Message) Methodları: Windows mesajlarını yakalayarak yönetebileceğiniz methodlara denir...

procedure MyMessage(Msg: Message); WM_MESSAGE;
şeklinde kullanılır...

Bütün bu konuları oldukça yüzeysel geçiyorum çünkü bunları derin derin inceleyeceğiz.. Başta da dediğim gibi siz henüz OOP konusunun saadece özetini görmektesiniz... Özet dedim de aklıma geldi... Abstract Methods denilen methodlar vardır... Bunlar için çoğu çevirmen kitaplarında Özet Methodlar olarak bahsedilmiştir. Ancak asıl olarak Abstarct Methods, Sanal Methodlar anlamına gelmektedir. Yapısı, amacı ve kullanım biçimi bakımından da incelediğimizde böyle olduğunu göreceksiniz.. Ancak yine de Özet Method da denilebilir.. Sebebini anlatmak için Abstarct Methods'u anlatmak gerekir:

Abstract Methods (Sanal Yöntemler): Şöyle bir sınıf düşünün, size İnsan sınıfını yaratabileceğiniz bir iskelet sunuyor. Yani kemikleri.. Ancak içi boş. Yani herhangi hiç bir tanım hemen hemen yapılamayacak durumda... Aldığınız o iskeletten yaratacağınız insan sınıfını istediğiniz gibi şekillendirebilir, içeriğini istediğiniz gibi belirleyebilirsiniz... İşte size bu türden (kimisinin değimiyle Özet, kimimizin değimiyle Sanal) içi boş yöntemler sunan sınıflara Abstarct Class denir... Bu yöntemlere ise Abstarct Methods adı verilir... Abstract ifadesi virtual methodlarda olduğu gibi kullanılır. Yani;

type
SanalSinif = Class
procedure Sanal; virtual; abstract;
end;

Bu prosedürleri normal virtual prosedürlerden ayırt etmek (anlam bakımından) çok zor olabilir sizin için... Ancak sınıf mimarisiniz anladığınızda bunun da avantajlarını göreceksiniz... Zaten bu konuya tam girebilmek için Polimorfizm'i anlatmak gerek... Daha sonra RTTI (Run Time Type Information - Çalışma Zamanı Tip Bilgileri) ve Sınıf yapısının derinliklerine doğru inilebilir...

Arkadaşlar çalıştığım için yazı yetiştirmem zor oluyor... Acil bir şekilde yazıyorum yazılarımı ve bundan dolayı istediğim kadar detaya inemiyorum... Ama yakında zorunlu olarak detaya ineceğim ve sağlam bilgiler edinmeniz için elimden geleni yapacağım... Şimdilik yine bu kadar... Hepinizden yorum ve eleşirilerinizi bekliyorum...


Polimorfizm: Öncelikle hatırlatmam gereken, Delphi’de yaptığınız her şey eğer farklı bir yöntem de içeriyorsa, biliniz ki kullandığınız yöntem ilgili yöntem grubunun static olanıdır... Walla çok karmaşık oldu ben bile anlamadım ne dediğimi eheue... Şöyle söyleyeyim: Örneğin bir procedure tanımladığınız zaman default olarak static tanımlamış olursunuz (Aksini belirtmediğiniz sürece)... Aynı şey functionlar için ve başka methodlar için de geçerlidir...

Polimorfizm yapısal olarak geç bağlama adı verilen tekniktir. Normalde Delphi Static bağlama tekniğini kullanır... Buna erken bağlama adı da verilebilir (Polimorfizm’in geç bağlama olarak nitelendirilmesinden dolayı. Ki teorik olarak bütün bunlar doğrudur).

Nedir Geç Bağlama?: Geç bağlamayı şöyle bir örnekle açalım; daha önceki örneklerimizden yola çıkarak yine ana sınıf olarak İnsan sınıfını ele alalım. Ve bu sınıfın yemek yemek anlamına gelen ye adında bir de proceduru olsun. İnsan sınıfına doğrudan bu proceduru kullandıramayacağınız için o sınıftan yeni sınıflar yaratmalı ve sonra da nesnelerinizi yaratmalısınız (İnsan sınıfı abstarct bir sınıftır). Bu ye proceduru insan sınıfından yaratılmış birden fazla nesneyi yönetirken kullandığınızı düşünün. Bu durumda her zamanki gibi dinamik kodlar yazmayı tercih edecek ve en kısa yöntemleri kullanacaksınız. Şimdi bütün bunlardan sonra aşağıyı iyi inceleyin ve sonraki soruyu iyi düşünün:

type
TInsan = Class
public
procedure ye; virtual;
constructor Create;
end;

TTaylan = Class(TInsan)
public
constructor Create;
procedure ye; override;
end;

TGurkan = Class(TInsan)
public
constructor Create;
procedure ye; override;
end;

sınıf tanımlarımız böyle olsun ve;

MyInsan: TInsan;

Şeklinde bir tanımlamaya karşılık MyInsan.ye çağrısıyla ye procedurune çağrıda bulunursak ne olur? İyi bir düşünün... Aslında Insan sınıfı yukarıda tam tanımlanmış göründüğü için pek bir şey olmaz... Ama sınıfı abstract yaratsaydık çok şey olurdu. Neyse... Peki yukarıdaki şekilde bir tanım yaptıktan sonra, MyInsan’ı TTaylan sınıfına atarsak ve onun “ye” yöntemini çağırırsak? İşte bu noktadan itibaren polimorfizmi anlatmak daha kolay. Kendinize sınıf hiyerarşisi oluşturuyorsanız bu konuyu iyi bilmeniz gerekir. Çünkü OOP’in en önemli konusudur Polimorfizm.

Yukarıdaki tanımdan sonra MyInsan: TInsan; gibi jenerik bir atama yaparak, her iki sınıfta da yöntem ismi aynı olan “ye” yöntemini çağırabilirsiniz. Bu durumda o an MyInsan’a yaptığınız atama hangi sınıfı işaret ediyorsa o sınıfın “ye” yöntemi çağırılır. Şimdi bunun üzerinden teorik tanımını yapmak gerekirse;
Polimorfizm, bir sınıf hiyerarşisi içerisinde istenilen sınıfın, kendisinin üstündeki sınıf yöntemleriyle aynı isimde method’lar yaratılabilmesini sağlayan, bunları jenerik atamayla kullanabilen bir tekniktir. En önemlisi, kodunuz içerisinde bu tekniği kullandığınızda, MyInsan’a atama yaparken derleyici onun o anki sınıfının ne olduğuna karar veremez. Ve bu çalışma anında belli olur. Buradan bir ipucuyla yola çıkarsak bir sonraki konumuzun RTTI (Run Time Type Information – Çalışma Zamanı Tip Bilgileri) olduğu ortaya çıkıyor...

var
MyGurkan: TGurkan;
MyTaylan: TTaylan;
begin
ye(MyGurkan);
ye(MyTaylan);
end;

procedure ye(MyInsan: TInsan);
begin
MyInsan.ye;
end;

Yukarıda da açıkça anlaşılabileceği gibi, MyInsan adında TInsan sınıfından bir yapıya, kendi çocuk sınıfları olan TGurkan ve TTaylan sınıflarından yaratılan MyGurkan ve MyTaylan nesnelerinin “ye” yöntemi çalışma zamanında tekrar tekrar değiştirilerek kullanılabilir...

Tekrar tekrar hatırlatırım ki, şu anda konuları teorik olarak kavramaya çalışmanızı, yani OOP aslında saadece fikir edinebilmenizi sağlıyoruz... Gerçek anlamda sınıflar yaratmaya ve kullanmaya, hatta VCL için component geliştirmeye başlarsak OOP konusunu örnekli olarak da görmüş olacaksınız...


1) GIRIS :
Java programlama dilinin en guclu yanlarindan biri nesneye yönelik (object-oriented bir programlama dili olmasidir. Javadaki butun nesneler object ana nesnesinden turer. Yani java c++ gibi hem prosedurel, hem de nesnel programlama degil, %100 nesneye yonelik programlama dilidir.
Bu chapter'da ilk olarak genel olarak nesne kavrami ve bunun java dilindeki uygulamalari , class kavrami , nesneye yonelik programlamanin temelleri olan kalitim ve polymorphism kavramlari anlatilacak, anlatilan her bir kavram orneklerle pekistirilecektir.

Nesne Kavrami :
Gercek hayattaki nesne kavrami elle tutulabilen, gozle gorulebilen herseydir. Ornegin masa, sandalye, elma hepsi birer nesnedir. Bu nesnelerin hepsinin ortak ozelligi belirli durumlari(nitelikleri), birtakim hareketleri ve bazi olaylari olmalaridir. Ornegin masa nesnesini ele alirsak boyu, yuksekligi nitelikleri, bir yerden bir yere hareket etmesi hareketi , uzerine birinin oturmasi ise bu nesnenin olayi olarak kabul edilebilir. Diger tum nesnelerin de buna benzer nitelik, hareket ve olaylari vardir.
Gercek hayat nesnelerinde dikkat edilecek bir diger nokta tum nesnelerin baska bir takim nesnelerden meydana gelmis olmasidir. Yine masa ornegini ele alirsak masa nesnesi sunta, civi,vb.. gibi bir takim nesnelerden meydana gelmistir, yani bir kalitim durumu vardir. Yine ayni sekilde her bir nesnenin ait oldugu bir tip vardir. Masa dedigimiz zaman genel bir kavramdir, oysa belirli bir masayi gosterdigimiz zaman belli bir nesnedir. Bu yuzden genel masa kavrami o nesnenin ait oldugu sinifi belli eder. Ayni sinifa ait nesneler benzer ozellikler gosterir.

Nesneye Yonelik Programlama Kavrami :
Nesneye yonelik programlama gercek hayat nesnelerinin yazilim kullanarak bilgisayar ortaminda modellenmesidir. Burada, gercek hayat nesnelerindeki durum degisken veya nitelik, hareketler ise metod adi verilen kod yordamlariyla temsil edilirler.
OOP(Object Oriented Programming) dili olmayan C, Pascal gibi dillerde veriler ve bunlar uzerine etki edecek program parcalari (fonksiyon, procedureler ) ayri ayri ele alinir. Onemli olan fonksiyonlardir, veriler ikinci plana atilmistir. Oysa bu yaklasim gercek hayat problemlerini cozmekte yetersiz kalmaktadir. Bu noktada ortaya cikan nesneye yonelik diller verileri ve onlarin uzerine etki edecek metodlari biraraya getirmis ve encapsulation dedigimiz olayi gerceklestirmislerdir.
Nesneye yonelik programlamanin asil gucu uzun ve karmasik programlarin yazilmasinda ortaya cikmaktadir. Yazilim gelistirme calismalari gostermistir ki, programcilar cogu kez program icindeki ufak detaylarla ugrasmaktan asil sorunu gozden kacirmaktadirlar. Nesneye yonelik programlama bu noktada devreye girer ve sagladigi cesitli tekniklerle agaclarin arasindan ormanin gorulmesini saglar. Bu islem soyutlama (abstraction) olarak adlandirilir.
Nesneye yonelik programlamadaki iki temel kavram kalitim (inheritance ) ve polymorphism'dir. Kalitmi yeni classlarin var olan classlardan ozelliklerinin aktarilmasi ve yeni ozellikler eklenmesi yoluyla yaratilmasi yontemidir. Kalitim program gelistirmede buyuk onemi olan yazilimin yeniden kullanilmasi olayinda buyuk onemi vardir. OOP'deki diger onemli kavram coksekillilik yani polymorphism'dir. Polymorphism bize ayri bir switch mantigina gerek duymadan programlarimizi genel bir mantik icinde yazmamizi ve var olan ve eklenecek classlari kullanabilmemizi saglar. Bu iki kavram bu chapterin ilerki bolumlerinde ayrintili bir bicimde ele alinacaktir.

Java ve Nesneye Yonelik Programlama :
Java tam bir nesneye yonelik dil oldugu icin yukarda sayilan kavramlari destekler. Java programcisi bir class(sinif) yazarken sinifa ait tumuyle yeni nitelik ve metodlar yazmak yerine var olan bir classi miras almak (inherit) yoluyla ona ait metod ve nitelikleri kullanabilir. Bu durumda miras alinan sinifa superclass, alan sinifa ise subclass adi verilir. Her bir subclass ilerde bir superclass olma adayidir.

Hierarside subclass bir ustunde yer alan class direct superclass, onun ustunde yer alanlar ise indirect superclass olarak adlandirilir.

Java dili C++'in yaptigi gibi coklu kalitimi desteklemez, tekli kalitimi destekler. Yani bir subclass'in ancak bir tane direct superclass'i olabilir. Bunun sebebi coklu kalitimin beraberinde birtakim sorunlari da getirmesidir. Oysa Java'nin sagladigi coklu arayuz(multiple interface) kullanimi coklu kalitimin sagladigi bircok ozelligi sunarken sorunlarin bir coguna yol acmaz.
Her bir nesne belli bir siniftan turer. Siniflar nesneleri ortaya cikaran sablonlar olarak dusunulebilir, aynen bir kek kalibi gibi ilk ortaya cikista birebir ayni olan nesneler gitgide farklilasirlar. Nesneler siniflarin ornekleri (instance) olarak adlandirilirlar. Java dilinde her bir subclassa ait nesne ayni zamanda superclassa ait bir nesne olarak da islem gorur. Bu ozellik farkli siniflardan olusturulmus nesnelerin tek bir nesne referansi uzerinden erisilebilmesini saglar ki bu ozellik nesneye yonelik programlamanin temel taslarindan biridir.
Java dili ayni zamanda metodlari farklilastirmaya(overriding) de izin verir ki bu ozellik miras alinan metodlarin farkli islemler yapabilmesini saglar.

2) SINIFLAR
Java dilinde programlamanin esasi sinif olusturmaktir. Giris bolumunde de anlatildigi gibi sinf(class) dedigimiz sey icinde bazi metod ve durum degiskenlerini kapsayan kod parcasidir. Her bir nesne belli bir siniftan meydana gelir. Bu sebepten dolayi siniflar nesnelerin turedigi tipler olarak dusunulur; sinirsiz sayida sinif yazma imkani oldugu icin Java dilinde istedigimiz kadar yeni tip meydana getirebiliriz.
Java dilinde bir sinifin genel tanimi asagidaki gibidir :
[Public|Private|Final|Abstract] Class [Sinif_Adi]
{
[Sinifa Ait Kodlar]
}
Sinifa Ait Uyeler :
Bir Java sinifinin icinde nitelik(instance variable), method ve olay yordamlari bulunur. Nitelik dedigimiz sey sinifin durumunu ifade eden genel veya yerel degiskenlerdir. Method sinifa ait hareketleri ve bunlarin nasil gerceklestirilecegini ifade eder. Bu sinifi kullanacak olan bir kullanici(client) bir metodun istenen bir isi nasil gerceklestirecegini bilmek zorunda degildir. Sadece ne yaptigini ve prototipini bilmesi metodu kullanmasi icin yeterlidir. Nesneye yonelik programlamaya ait bu ozellik soyutlama(abstraction) olarak adlandirilir. Bir java sinifina ait ucuncu bir uye vardir. Bu uye sinifin uzerine etki edebilecek olaylar karsisinda aktif hale gelen olay yordamlaridir ve gorsel programlamanin temelini olusturmaktadir.
Sinifa ait uyelerin etki alanlari vardir. Bu erisim alanlari; Public, Private ve Protected anahtar kelimeleriyle tanimlanir. Public olarak tanimlanan uyeler hem sinif icinde, hem de bu sinftan turetilen nesneler yoluyla istemciler tarafindan kullanilabilir. Yani sinifin disariya sunmus oldugu servislerdir. Private tanimlanan uyeler ise sadece tanimlandigi sinif icinde kullanilabilir, bu uyelere disardan direkt erisim yoktur, ancak Public uyeler uzerinden erisim saglanabilir. Private uyeler bilgi saklama(information hiding) dedigimiz kavrama hizmet ederler. Bunlarin disinda Java dilinde ozel bir erisim tanimi olan Protected, Public ve Private erisimler arasinda gecis teskil eder. Sinif icinde Protected olarak tanimlanan uyeler superclass'in methodlari, subclass'in methodlari ayni paketteki diger siniflar tarafindan kullanilabilir.
public class Merhaba()
{
public int X;
public int Y;
private int Z;
protected String kelime;
public **** Merhaba()
{
System.out.println(kelime);
X=10;
Y=20;
}
}
Ornek 2-1 : Ornek bir Java sinifi


SuperClass ve SubClass'lar :
Giris bolumunde de anlatildigi gibi siniflar metod ve nitelikleri birbirinden miras alarak buyurler. Miras veren sinifa superclass, miras alana ise subclass denir. Ilk bakista celiski gibi gorunse de miras verene superclass denmesinin sebebi subclass'tan turetilen her bir nesnenin ayni zamanda superclass'in da bir nesnesi olmasidir.


Ornegin bir dikdortgen sinifi dortgen sinifini inherit etmis(miras almis durumdadir). Bu yuzden dikdortgen sinifindan turetilen her bir nesne ayni zamanda dortgen sinifina da ait bir nesnedir.

Nesneler arasindaki kalitim iliskileri agac tipli hierarsik yapilar ortaya cikarir. Bu yapidaki superclass'lar ustte, sub classlar altta yer alir. Eger sinif yalniz basina kullaniliyorsa superclass, subclass gibi nitelikler almaz, bu nitelikler sinif hierarsi yapisinin icinde kullaniliyorsa gereklidir.
Sekil-1 : Universite Mensuplari Hierarsi Semasi
Bir Subclassa ait nesne superclass'a ait bir nesne gibi islem gorur. Bu ozellik cogu zaman yararli manipulasyonlar yapmamizi saglar. Ornegin ayni superclass'tan tureyen farkli subclass nesneleri bu ozellik kullanilarak tek bir arrayin elemanlari olabilirler. Aradaki cevrim gizli olarak yapilir.

Onemli Not : Fakat bir superclass nesnesi otomatik olarak bir subclass nesnesi olarak degerlendirilemez. Boyle bir degerlendirme bir syntax hatasina yol acar. Ancak programci, bir superclass referansini bir subclass referansina donusturmek icin acik bir deyim(cast) kullanabilir. Bu kullanim sekli ancak superclass referansi bir subclass nesnesini isaret ederken yapilabilir. Aksi taktirde Java ClassCastException hatasi verecektir.

Ornek ! Java Dilindeki Subclass ve Superclass Iliskileri Ornekleri Icin Tiklayiniz !
Constructor-Finalizer Kavramlari ve Bunlarin Subclasslarda Kullanimi :
Bir siniftan bir nesne yaratildiginda implicit olarak calisan ve bu nesneye ait baslangic islemlerini yapan sinif metoduna constructor adi verilir. Ayni sinif icinde parametreli ve parametresiz olmak uzere iki adet constructor tanimlanabilir. Parametresiz constructor sinifin varsayilan(default) constructor'idir.
Finalizer ise nesne implicit veya explicit olarak yokedilecegi zaman calisan nesneye ait metottur.


Ornek : Asagida bir nokta nesnesine ait constructor ve finalizer metodlari gorulmektedir.
public class Nokta
{
protected int x,y;
//parametresiz constructor
public point()
{
setPoint(0,0);
System.out.println("Nokta constructor : "+ toString());
}
//parametreli constructor
public point(int a,int b)
{
setPoint(a,b);
System.out.println("Nokta constructor : "+ toString());
}
//finalizer
protected **** finalize() throws Throwable
{
System.out.println("Nokta Finalizer :
super.finalize();
}
public **** setPoint(int a, int b)
{
x=a;
y=b;
}
public String toString()
{
return "["+ x + ", " + y + "]";
}
}
Ornek 2-2 : Constructor ve Finalizer Methodlarinin Kullanimi

Ornek 2-2'de goruldugu gibi bir sinifa ait construcor metodu sinifin ismini alir. Eger bu siniftan bir nesne yaratilirken parametre verilmezse parametresiz constructor sinifi, parametre verilirse parametreli constructor sinifi calisir. Ornekte nesneye ait finalizer metodu degisik bir prototipte tanimlanmistir. Bunun sebebi bu metodun Object ana sinifinda bu sekilde tanimlanmis olmasi, ve bu siniftaki metodun aslinda o metodu override etmesidir. Bu prototipin aciklamasi bu asamada bizim icin onemli degildir. Bizim bilmemiz gereken finalize metodlarinin bu sekilde yazilacagidir.
Simdiye kadar anlatilan constructor-finalizer kavramlari tek bir sinifli durumlar icindir . Oysa OOP'da siniflar cogu kez bir hierarsi icinde subclass-superclass mantigi icinde kullanilir. Bir subclass'tan bir nesne turetildiginde ilk olarak bu subclassa ait superclass'in constructor metodunu cagirmasi gerekir. Bunu saglamak icin superclass referansi acik olarak cagrilabilir(bak.aciklama-1); eger bu yapilmazsa subclass'a ait constructor metodu superclass'in default constructor'ini implicit olarak cagiracaktir.


Aciklama-1 : Subclass uzerinden superclass constructor'ini cagirmanin yolu 'super()' deyimini kullanmaktan gecer.Eger subclass'ta superclass constructor'i explicit olarak cagrilmazsa bu durumda superclass'in default constructor'i implicit olarak calistirilir. Eger default constructor (parametresiz olan) mevcut degilse bu durumda bir syntax hatasi meydana gelir.



Aciklama-2 : Superclass constructorlari subclass constructorlari tarafindan miras alinmazlar. Bir subclass nesnesi yaratildigi zaman ilk olarak superclass constructor'i calisir, daha sonra subclass constructor'i calisir.

Finalizer Metodu : Constructorlardan farkli olarak bir sinifin bir tane finalizer metodu vardir. Bir subclass'in finalizer metodunun son statementi daima super.finalize() metodu olmalidir ki, superclass'in finalizer metodunun calismasi garantilensin.
Ornek ! Constructor ve Finalizer'larin Kullanimina Iliskin Ornekler Icin Tiklayiniz !
Superclass Nesnelerinin Subclass Nesnelerine Cevrimi :
Superclass nesnelerinin ayni zamanda bir subclass nesnesi olmasi gercegine ragmen, sub ve superclass nesnelerinin tipleri birbirinden farklidir. Subclass nesneleri superclass nesneleri gibi muamele gorebilir. Bunun sebebi subclass'ta superclass'taki her bir uyeye karsilik gelen bir uye bulunmasidir. Oysa bunun tersi dogru degildir; cunku bir superclass nesnesini subclass nesnesine atamak sadece subclass'ta bulunan uyeleri acikta birakacaktir.


Dikkat ! Once bir subclass nesnesini bir superclass referansina atamak, daha sonra ise subclass'a ozgu uyeleri superclass referansi uzerinden kullanmak bir syntax hatasina yol acar.

Bir subclass nesnesi gizli olarak bir superclass nesnesine cevrilebilir, cunku kalitimdan dolayi bir subclass nesnesi ayni zamanda bir superclass nesnesidir. Superclass ve subclass referanslariyla superclass ve subclass nesnelerini eslestirmek ve karistirmak icin dort farkli yontem vardir :
 Bir superclass nesnesine superclass referansiyla erismek
 Bir subclass nesnesine subclass referansiyla erismek
 Bir subclass nesnesine superclass referansiyla erismek, cunku cevrim implicit olarak yapilir.
 Bir superclass nesnesine subclass referansiyla erismek ise syntax hatasina yol acar. Bu yol uygulanacak ise once subclass referansi casting islemine tabi tutulmalidir.

Kalitim Nedir ?
Nesneye yonelik programlamanin temellerinden olan kalitim(inheritance) yeni siniflar yazarken elimizde var olan siniflari kullanmamizi saglar. Yeni sinifin bircok ozelligi eski yazilan sinifla aynidir. Kalitim yoluyla yeni sinifta bu uyeleri tekrardan yazmaya gerek kalmaz. Bazi uyeler ise farklidir (eger tum uyeler ayni olsa yeni sinif yazmaya gerek kalmazdi!); eger bu uyelerin tanimlamalari superclass'ta mevcutsa bu durumda bunlar farklilastirilir (overriding), yani gerceklestirimleri degistirilir. Eger yeni eklenecek uyelerin prototipleri superclasst'ta mevcut degilse bunlar direkt olarak yeni sinifa(subclass) eklenebilir.
Kalitim, yazilimin yeniden kullanilmasi ihtiyacina buyuk olcude katkida bulunur. Zaten kalitim kavraminin ortaya cikmasinin sebebi , ozellikle buyuk capli yazilim gelistirme calismalarinda ayni kod parcalarinin tekrar tekrar kullanilmasini onlemek ve yeni siniflari var olanlarin ustune insa etmektir. Gercek hayattaki nesne modeli de buna uygundur.
Kalitim kullaniminda hizmet eden en onemli kavramlardan biri soyutlama (abstraction)'dir. Bu yontem sayesinde kalitilan nesnenin istenen islemleri nasil gerceklestirdiginden cok ne yaptigiyla ilgilenilir. Kalitilan nesnede yapilacak uygulama degisikleri sonucu etkilemedikten sonra subclass'lari etkilemez.


Ornegin : Bir sinifin bir listeyi array'de mi, link list'te mi, yoksa bir tree yapisinda mi tuttugu bu sinifin subclass'larini etkilemez.

Bir superclass'tan kalitim yoluyla tureyen tum siniflar bir hierarsi yapisi meydana getirirler. Bu yapinin en ustunde superclass yer alir ve geneli ifade eder. Bu superclass'tan tureyen tum subclass'lar, superclass'in ozelliklerini alirlar. (Superclass-Subclas Icin Bkz Sinif Bolumu)


Oneri ! Nesneye yonelik programlama yapan bir Java programcisi once ortak ozellik ve davranislari belirleyip bunlari bir sinifa koymali, daha sonra ise bu sinifin ozelliklerini genisleten subclass'lar yaratmalidir.

Java Dilinde Kalitimin Uygulanmasi :
Java dili tekli kalitimi destekler, yani bir alt sinifin ancak bir direkt super sinifi olabilir. Java'da kalitimi saglamak icin 'extends' anahtar sozcugu kullanilir. Ornegin bir Java appleti hazirlayabilmek icin yaratacagimiz sinif sistem tanimli Applet sinifini inherit etmek zorundadir.
public class ornek extends Applet
{
..
}
Bu ornekte Applet sinifi superclass, ornek adli yeni yaratilan sinif ise subclass ismini alir.
Java'daki her bir subclass bir superclass olma adayidir. Ancak final olarak tanimlanan siniflardan yeni sinif tureyemez, yani bunlar superclass olamazlar.
Java dilindeki kaltim is-a yonteminin uygulanmasidir.

4)POLYMORPHISM
Polymorphism (Coksekillilik) Nedir ?
Polymorphism nesneye yonelik programlamanin kalitimdan sonra ikinci temel yapitasidir. Polymorphism sayesinde kolaylikla genisleyebilen sistemler tasarlamak ve uygulamak mumkundur. Programlar hierarside var olan ve eklenecek tum nesneleri isleyecek tarzda genel olarak yazilir. Bunu saglamanin yolu tum nesnelere ortak bir referansi uzerinden erismektir. Bu referans tum nesneler icin ortak olan superclass nesnesi referansidir. Sisteme bu hierarsi icinde yeni siniflar eklemek kod icinde sadece yeni sinifi direkt olarak bilen bolumlerde degisiklige yol acacaktir.
Polymorphism ve Switch Mantigi :
Birden fazla nesneyi ayni referansla ele almak icin polymorphismin tersi olan mantiga switch mantigi adi verilir. Bu mantik sinif icinde bir switch veya if ifadesinin bulunmasini ve ele alinmak istenen nesnenin bir sekilde belli edilerek uygun case bloguna girmesini gerektirir. Hangi nesnenin ele alinmak istendigi cogu kez sinif icinde bulunan public bir saha araciligiyla belirlenir. Ornegin bir nokta sinifina ait tip sahasina bakilarak bu sinifa ait nesnenin bir kare mi, yoksa bir dikdortgeni mi refer ettigine karar verilir.
Ancak, switch mantiginin bir cok sorunu vardir. Programci sinifin kastettigi her turlu tipin kontrolunu unutabilir , sisteme yeni tipler eklenmesi kod uzerinde buyuk degisikliklere yol acar.
Polymorphism switch mantiginin alternatifidir ve onun yol actigi bir cok sorunu onler. Polymorphism'de asagida anlatilan dinamik baglama(dynamic binding) sayesinde ayni isimle cagrilan bir metod nesne referansinin o an gosterdigi nesneye gore farkli islemler yapabilir, bu da switch mantigina olan gereksinimi ortadan kaldirir.


Yarari ! Polymorphism programlarin daha basit bir gorunuse kavusmasini saglar, bu da programlarin test, debug ve maintanance gibi islemlerini basitlestirir.

Dinamik Metod Baglama(Dynamic Method Binding) Kavrami :
Nesneye yonelik programlamada bir superclass'i miras alan butun subclasslar o superclass'a ait metodlara sahip olurlar. Polymorphism sayesinde ise subclass nesnelerine superclass nesnesi uzerinden erisim saglanabilir. Ancak bu nesne uzerinden bir metoda erismek istedigimiz zaman ortaya bir sorun cikar, ayni metod superclass'ta da oldugu icin hangisinin metoduna erisilecektir. Iste dinamik metod baglama burda ortaya cikar ve metodlarin nesnelere derleme zamaninda degil, isletim zamaninda baglanmasini saglar. Bu sayede metodlar nesne referanslarinin o an gosterdigi nesneye uygun olarak calisir.


Ornek ! Bu kavrami daha iyi anlamak icin bir ornek verelim. Kare, dikdortgen, ucgen ve daire subclass'larinin sekil superclass'indan meydana geldigini dusunelim. Sekil sinifinda olan ciz metodu her alt sinifa gececek ve bu siniflarda farklilastirilacaktir. Eger tum siniflara ait nesneleri sadece sekil sinifindan olusturulmus bir nesneyle ele alirsak, bu nesnenin ciz metodunu kullandigimiz zaman program otomatik olarak bu nesne referansi uzerinde o an baglanmis nesneyi tespit edecek ve ona ait ciz metodunu calistiracaktir.

Abstract ve Concrete Siniflar :
Sinifi bir tip olarak dusundugumuz zaman, bu tipe ait nesneler turetilecegini varsayariz. Oysa, bazi durumlarda programcinin asla nesne turetmeyecegi siniflar yazmak gerekli olabilir. Bu tip siniflara soyut(abstract) sinif adi verilir. Abstract siniflardan nesne turetilemez. Abstract siniflarin amaci, diger siniflarin miras alabilecegi bir superclass yaratmaktir. Java dilinde bir sinif basina abstract sozcugunun gelmesiyle abstract hale gelir.
Abstract siniflarin tam tersine uzerinden nesnelerin turetilebilecegi siniflara concrete siniflar denir.
Asagida abstract bir sinif ornegi verilmektedir.
public abstract class ogrenci
{
private String ad;
private String soyad;
public ogrenci(String ilk, String son)
{
ad=ilk;
son=soyad;
}
public String alAd()
{
return ad;
}
public String alSoyad()
{
return soyad;
}
abstract int notlar();
}
Ornek-1 : Abstract Sinif ve Metodlar
Ornek-1 soyut bir siniftir. Sinifin en altinda yer alan notlar metodu abstract bir metod olup ogrenci sinifini miras alan her alt sinif tarafindan tamamlanmak zorundadir.
 
Ü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.