"Enter"a basıp içeriğe geçin

OOP

 

Java nesne tabanlı bir programlama dilidir.
Nesne tabanlı programlamayı detaylandıralım:

Nesne tabanlı programlama, gerçek dünyanın bilgisayar ortamına aktarımını kolaylaştırma amacı taşıyan bir programlama türüdür. Nesne tabanlı programlamada ise her şey nesnelere dayalıdır. Tasarlayacağımız programda ihtiyacımız olacak ögeleri ortak özelliklerine göre ayırıp, bu özellikleri sağlayacak sınıflar oluştururuz. Java dilinde her işlev için bir sınıf oluşturulması gerekir.

Nesne tabanlı programlamanın bize sağlayacağı temel faydalar:

  1. Gerçek dünyayı bilgisayar ortamına daha kolay ve etkili aktarabiliriz. Çünkü gerçek dünyada da programımızda olduğu gibi, her şey nesnelerden oluşur Kod tekrarı en aza iner.
  2. Nesneleri ortak özelliklerine göre sınıflayıp sınıfımızı ona göre tasarladığımız için, a nesnesi için yazdığımız kodu tekrar yazmadan b nesnesi için de kullanabiliriz.
    Örneğin bir oyun tasarlıyoruz. Tüm karakterler için belli başlı ortak özellikler vardır. Her bir karakter için aynı kodları tekrar tekrar yazmak yerine, bu özellikleri bir sınıfta toplarız ve karakterlerimizi de bu sınıflar üzerinden oluştururuz. Her bir karakterimiz, sınıfa ait bir nesne olur.
  3. Nesneler arası bağlantı az olduğundan ve kapsülleme gibi yöntemlerin varlığından dolayı çok daha güvenli kodlar yazmamızı sağlar.

Bunların hepsi diğer OOP dillerinde de geçerliydi, ancak java tamamen class’lara dayalı bir dil olduğu için çok daha aktif şekilde kullanırız.

Sınıflar için nesne tabanlı programlamanın temelidir diyebiliriz.

Gerçek hayattan aktaracağımız ilk nesne bir öğrenci olsun. Her öğrencinin belli özellikleri vardır. Adı, soyadı, öğrenci numarası, boyu, kilosu, sınıfı…
Bir okulda yüzlerce öğrenci olabilir. Her biri için tek tek aynı kodu yazmak çok fazla zaman alır. Ayrıca diyelim ki yeni bir özellik eklememiz gerekti. Hepsi için bu özelliği tek tek eklememiz gerekirdi.
Bunun yerine öğrenci diye bir class oluşturursak bu class her öğrenci için bir şablon olur. Sınıfı bir kere yazarız ve her yeni öğrenci tüm özelliklerini bu şablona göre alır.
Yeni bir özellik ekleyeceğimiz zaman tek yapmamız gereken sınıfın içeriğini değiştirmektir.

Ayrıca öğrenciler için işlevler tanımlamamız gerekebilir. Ve bu metodlar her öğrenci için kendi özelliklerine göre çalışmalıdır. Sınıfımızın içine metodlarıda eklersek bu işlevleri de kolay bir şekilde ekleyebilir ve çalıştırabiliriz.

Sınıflarda bulunan değişkenler ve metodların her birine sınıfın bir üyesi denir.

Daha önce Main adında bir sınıf oluşturmuştuk, ama neyin ne işe yaradığından bahsetmemiştik. Bu konuları biraz daha detaylandıralım.

İlk bahsetmemiz gereken şey erişim ifadeleridir.
Nesne tabanlı programlamada 3 adet erişim ifadesi mevcuttur. Biz şimdilik Public ve Private ifadelerini göreceğiz. Diğerleri için şu konuya bakabilirsiniz

Public herhangi bir yerden erişilebilir demektir. Yani public olarak ifade edilen şeyleri her yerde kullanabiliriz.

Private ise o sınıfa özel demektir. Private kısımda bulunan değişkenlere, metodlara sadece sınıfın içinden ulaşabiliriz. Mesela öğrenci numarası private ise, sadece sınıfın içinde tanımlayacağımız, sınıfın kendi metodları bu değişkeni kullanabilir. Başka sınıflar veya sınıfın dışındaki fonksiyonlar bu değişkene erişemez.

Yeni bir sınıf oluşturmak için, paket dizinimizde sağ tık yaparak new class diyoruz.

Class seçiyoruz ve public sınıfın ismini veriyoruz.

 

Öğrenci adında bir dosya oluştu, ve içinde dosya ismi ile aynı, ama boş bir Öğrenci sınıfı var.

Sınıfımızın kalıbını oluşturalım:

Oluşturduğumuz her öğrenci nesnesi bu kalıba göre oluşacak. Ahmet diye bir nesne oluşturduğumuzda hafızada bir yer alınacak ve bu yerde Ahmet nesnesinin isim, numara,yaş,sınıf,kilo ve boy değişkenleri için bir yer olacak.

Ali nesnesi oluştuğunda başka bir yer hafızadan alınacak. onun içinde de bu özellikler olacak ama Ahmet’in yaş değişkeni ile Ali’nin yaş değişkeni hafızada farklı yerlerde olduğu için birbirini etkilemeyecektir.

Dosyalar

Java dilinde tek program için birden çok java dosyası olabilir. Örneğin main sınıfımızı başka bir dosyaya, öğrenci sınıfımızı başka bir dosyaya yazmamız gerekir.

Çünkü ikisi de public sınıflardır ve önceki derslerimizde her dosyada sadece 1 public sınıf olabileceğini söylemiştik. Programı çalıştırdığımızda main sınıfındaki main metodu çalışmaya başlar. Bu durumda main sınıfı, öğrenci sınıfına erişebilmelidir.

public class dediğimiz için diğer java dosyaları bu sınıfa erişebilir. Yani Main sınıfı da erişebilir.
private class deseydik, bu sınıfa sadece bulunduğumuz java dosyasından erişebilirdik.
Ayrıca protected ifadesi de vardır. Protected olarak tanımlanan metodlara sadece aynı dosyadaki sınıflardan erişilebilir.

şimdi oluşturduğumuz public sınıfın içine girelim.

Burda karşımıza başka bir public çıktı. Önceki public sınıfın kendini public yapmıştı. Yani programın her dosyasından bu sınıfa erişilebilmeyi sağlamıştı. Sınıfın içindeki public ve private ise sınıftaki değişkenlerin diğer sınıflar tarafından kullanılıp kullanılamayacağını gösterir.

public değişken ve metodlar diğer sınıflar tarafından kullanılabilir. (başka dosyadaki sınıfların kullanabilmesi için sınıfın da public olması gerekir. Sınıf private ve üye public ise sadece mevcut dosyadaki sınıflar erişebilir.)

private değişken ve metodlar sadece mevcut sınıf içinde kullanılabilir. Diğer sınıflar bu üyelere doğrudan ulaşamaz.

şimdi main class’ımızın içinde öğrenci sınıfına ait bir öğrenci nesnesi oluşturalım.

Öğrenci, sınıfımızın adıdır. ilhan ise bu sınıfa ait bir nesnedir.

new Öğrenci() dediğimizde, hafızada Öğrenci cinsinden bir yer ayrılır ve o yerde bir öğrenci nesnesi oluşur. Ama bu nesnenin hafızanın hangi adresinde tutulduğunu biz bilemeyiz. Öğrenci ilhan = new Öğrenci(); dediğimizde ise, oluşturulan adresi göstermesi için ilhan adında ve öğrenci tipinde bir referans oluşturulur. Öğrenci furkan=ilhan; dersek referansları eşitlediğimiz için ilhan ve furkan aynı nesneyi gösterir.
Referanslardan daha sonra detaylı bahsedeceğiz, burası anlaşılmadıysa hızlı geçebilirsiniz.

 

Öğrenci sınıfına ait, ilhan adında bir öğrenci oluşturduk. Artık ilhan’ın isim, numara, sınıf, boy, kilo gibi özellikleri var. Ama bu değişkenlere herhangi bir değer atamadık. Bu yüzden şimdilik boşlar.

Bir nesneye ait üyelere erişmek için nesne.üye kalıbını kullanırız.

 

ilhan ve ahmet adında iki öğrenci oluşturduk. İkisi de Öğrenci sınıfının nesneleri. Bu yüzden isim, numara, sınıf, boy, kilo özellikleri var. Ama birbirlerinden bağımsız nesneler. Bu yüzden birinin bir özelliği diğerini etkilemiyor.
Nesnelerin öellikleri atanmadığı için başlangıçta boştu. İki nesne için de özelliklere ilk değerleri verdik ve yazdırdık.

İsim ve numara public üyeler oldukları için başka bir sınıf olan main’de kullanırken sıkıntı yaşamadık. Peki private üyelere main ile erişmeye çalışsaydık?

Bu sefer hata aldık. Çünkü yaş private bir değişken. Ve private değişkenlere sadece sınıfın içinden ulaşılabilir. Peki yaş değişkenine erişmek istersem ne yapmalıyım?
Bunun için bir public metod oluşturabiliriz. Bu metod yaş değişkenine erişmemizi veya yazdırmamızı sağlayabilir.

 

private üyelere dolaylı yoldan erişebilmek için setter-getter metodlar kullanılır. Yaş değişkeninin neden dışarıdan erişime kapalı olduğunu bu kod ile daha iyi görüyoruz.
Eğer herhangi bir yerden erişebilseydik, bir kontrol mekanizması olmadığı için yaş değişkenine negatif bir sayı girilebilirdi. Bu da mantık hatasına neden olurdu.
Yaş değişkenini dışarıdan erişime kapadık. setter-getter fonksiyonlar sayesinde dolaylı bir erişim sağladık ve bu fonksiyonlara kontrol mekanizması ekledik.
Artık yaş değişkenine geçersiz bir değer girilemez.

Bu kontrolün birçok sebebi olabilir. Grup projelerde bizim sınıfımızı başkaları da kullanır. Başkaları sınıfımızın içeriğini tam bilmediği için bir değişkene hatalı bir değer girebilir (yaşa sıfır girmek gibi) .
Veya metodun içine bakmadan, sadece input-output ile ilgilenilebilir.
Mesela matematiksel hesaplamalar yapan bir sınıfımız olsun. Bu sınıfta da pi değişkeni 3.14 olarak tanımlansın. pi değişkeninin değerinin dışarıdan değişmemesi gerekir. Ama pi değişkeni diğer hesaplama metodları için gereklidir.
Bu yüzden pi değişkeni private olmalıdır.

Az önce yaptığımız gibi, private üyeler kullanarak üyelere erişimi kısıtlamaya ve sınırlı erişim sağlamaya encapsulation (kapsulleme) denir.

Değişkenler gibi metodlar da nesneye özeldir. Yani bir nesnenin metodları, o nesnenin değişkenlerini kullanır.

 

this anahtar kelimesi

Üye fonksiyonlarda, parametrenin ismi sınıftaki başka bir üyenin ismiyle aynı olabilir. Bu karışıklığa yol açar.

Gördüğünüz gibi şuanda çok karışık bir durum oluştu. Hangisi parametre ile gelen yaş değişkeni, hangisi nesneye ait üye değişken belli değil.

Ama parametreye anlamsız isimler vermek de her zaman iyi olmayabilir. Mesela 10 tane parametre alan bir fonksiyonumuz olsun. Tek tek a,b,c,d,e,f,g,h,i,j diye değişken ismi verirsek, hangi değişkenin ne olduğunu aklımızda utmamız imkansız olur.
Yani gelen parametre değişkeni ile üye değişkenin aynı adda olmasının işimize yarayacağı zamanlarda olabilir.

Parametre ile üye arasındaki farkın anlaşılması için this kelimesi kullanılır.

 

Burada this.yaş diye belirtilen değişken, üye olan yaş değişkenidir. Diğerleri ise parametre olarak gelen yaş değişkenidir.

Yani eğer sınıfın içindeki bir fonksiyonda sınıfın bir üyesine erişmek istediğimizde this. ile de erişebiliriz. Fonksiyon hangi nesne için çağrılıyorsa, this yerine o nesne gelir.

Ancak eğer az önceki gibi kafamızı karıştıran (üye ile parametrenin aynı isimde olduğu) bir durum yoksa this. kullanmamıza gerek yoktur. Çünkü derleyici, o değişkenin üye değişken olduğunu bilir.

Constructor

Bir nesne oluşurduğumuzda, biz ekleyene kadar üyelerin içi boş kalıyordu. İsim, numara gibi değerleri nesne oluşturma sırasında vermek isteyebiliriz.

Bunun için constructor denen yapıcı metodlar kullanılır. Yapıcı metodlar nesne oluştuğu anda otomatik olarak çağırılır ve üye değişkenlere ilk değerlerini verir (ilklendirme yapar).
Normalde biz oluşturmasak da derleyici bizim yerimize bir constructor oluşturur. Ve nesneyi oluşturduğumuz anda otomatik çağırılır. Ama bu constructor değişkenlere 0 veya null gibi değerler atar (daha önceki örneğimizde görmüştük)

Bir constructor oluşturalım:
Constructor metodların adı sınıf ile aynı olmalıdır. Return tipleri yoktur. Ve yapıcı metodlar public yazılmalıdır.

Yani yapıcı metodlar public sınıfismi(){ } formatında olmalıdır.

Öğrenci(“İlhan Furkan Sadıkoğlu”,15157, 20); dediğimiz için constructor otomatik olarak çalıştı ve üye değişkenlere otomatik olarak ilk değerini verdi.
print fonksiyonu ile de tüm bilgileri yazdırdık.

Dikkat ettiyseniz, yaş değişkenini değiştirmemizi sağlayan işlevi tekrar yazmak yerine daha önceden yazdığımız setter fonksiyonu kullandık.

Yapıcı metodların içinde setter metodlar kullanmak kodumuzu sade ve daha anlaşılır bir hale getirir.

Default Constructor

Hiç paremetre almayan bir constructor da yazılabilir. Buna default constructor denir. Bu constructor ile oluşturulan tüm nesneler önceden belirlenmiş değerlerle oluşturulur.
Derleyicinin bizim için otomatik oluşturduğu yapıcı da aslında bir default constructor’dur. Zaten en başta new Öğrenci() dediğimizde de o çalıştı.

Derleyicinin bizim için otomatik oluşturduğu varsayılan yapıcı, biz en az 1 tane yapıcı yazdığımızda otomatik silinirdi.
Bu durumda yukarıdaki kodun main kısmını şu şekilde değiştirirsek

Hata verir. Çünkü herhangi bir varsayılan yapıcı yoktur. Derleyicinin verdiği iptal oldu.

Metodların aşırı yüklenebilmesinden bahsetmiştik. Bu tabi ki yapıcı metodlar için de geçerlidir.
Farklı sayıda parametre alan yapıcı metodlar yazabiliriz. Nesneyi oluştururken kullandığımız imza hangi yapıcı metoda uyuyorsa o çalışır.

Her bir nesne için imzasına uygun olan fonksiyon çağırıldı. Fonksiyonlar da aldığı parametrelere uygun şekilde yazıldı. Örneğin Hiç parametre almayan default constructor tüm değişkenlere otomatik olarak varsayılan değer atadı.
Diğer yapıcılarda da aynı şekilde, gelen parametreler yerine kondu, diğer değişkenler için ise kendi belirlediğimiz varsayılan değer yazıldı.

Ama sanki böyle de çok uzun oldu dediğinizi duyar gibiyim. Metod içinde metod kullanma yapıcı metodlarda da geçerlidir. Yani bir yapıcı metodun içinde başka bir yapıcı metod da çağırabiliriz.
En geniş kapsamlı yapıcı metodu yazıp, diğer yapıcı metodlarda da bunu çağırırsak amacımıza ulaşmış oluruz.

İlk oluşturduğumuz constructor’u diğerlerinde kullanarak işimizi kolaylaştırdık.

 

IDE Generate özelliği

Getter-setter ve Constructor gibi genel fonksiyonları hızlıca oluşturmak için IDE’deki generate seçeneğini kullanabiliriz.

Oluşturulacak constructor içinde hangi özellikler olması gerektiğini soruyor. ctrl ile birden çok seçebiliriz. Mesela 3 tane özelliğimiz varken 2 tanesini constructor ile ilklendirmemiz gerekiyorsa, sadece bu ikisini seçeriz. Ben 3’ünü de seçiyorum.

3 özelliği de ilklendiren constructo oluştu

İstersem setter-getter  seçerek onları da oluşturabilirim.

Kendim tek tek yazmak ile uğraşmadan, bikaç tuşa basarak tüm özellikler için getter-setter ve constructor oluşturdum.

Static Anahtar kelimesi

Bazen sınıfın tamamında ortak kullanılacak değişkenlere ihtiyacımız olabilir.
Bu durumda static anahtar kelimesi kullanılır. Static olarak tanımlanan değişkenler, o sınıfa ait tüm nesneler tarafından erişilebilir. Yani belli bir nesneye değil, sınıfın tamamına ait olurlar.
Normalde bir sınıf yazılsa da, o sınıfa ait bir nesne oluşturulunana kadar içindeki üyeler hafızada(heap) tutulmaz.
Ancak static değişkenler, program çalıştırıldığı anda hafızada oluşturulur. Bu yüzden bu üyelere herhangi bir nesne oluşturmadan da erişebiliriz.
static değişkenler sınıfın tamamına ait olduğu için değişirse tüm nesneler bu değişiklikten etkilenir.
Mesela static değişkenleri, o sınıfa ait kaç tane nesne oluşturduğumuzu tutmak için kullanabiliriz.

static değişkenlerin getter-setter metodları da static olmalıdır.

Fonksiyonlar da static olabilir.
static olmayan fonksiyonlar nesne oluşmadan kullanılamaz. Bu fonksiyonlar da aynı değişkenler gibi, sınıfın tamamına aittir ve nesneden bağımsız çalışabilirler.
static olmayan değişkenler de nesne oluşturulana kadar hafızada yer almazlar. Bu yüzden static bir fonksiyonda static olmayan bir değişken kullanamayız.

Aynı sebepten, eğer constructor içinde parametre olarak gelmeyen ve o blok içinde oluşturulmayan bir değişken kullanmak istiyorsak, bu değişkeni static olarak tanımlamamız gerekir. Çünkü constructor çalıştığında nesne henüz oluşmamış olduğu için static olmayan değişkenler de henüz oluşmamıştır.

İnsan sınıfı:

 

Main sınıfı:

    Bir cevap yazın

    E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir