Merhaba bundan önceki yazımda Nesneye yönelik programlama temellerini anlatmıştım. Şimdi ise önceden öğrendiğimiz bilgiler üzerine yeni bilgiler ekleyelim.

Nesneye Yönelik Programlama – Object Oriented Programming Nedir-2 ?

Merhaba bundan önceki yazımda Nesneye yönelik programlama temellerini anlatmıştım. Şimdi ise önceden öğrendiğimiz bilgiler üzerine yeni bilgiler ekleyelim.

Öncelikle bu makalemde anlattıklarımı daha iyi anlamanız için bundan önce anlattığım konuları bilmeniz sizin için daha iyi olacaktır. İlk yazımı okumadıysanız buraya tıklayarak okuyunuz.

public ve private Erişim Belirteçleri (Access Modifiers)

Her değer veya fonksiyon mutlaka bir class'ın içinde yer alır.Uygulamalar bazı özel koşullara sahip (class) lardır. Bir class uygulama olarak çalştırılacağı zaman “main” method'unu bulur ve oradan itibaren çalıştırır.Bulamazsa sınıfta main metodu yok çalıştıramam diyerek hata mesajı ile döner.
hız değişkeni ise private yani sınıfa özel bir değişken. Araba sınıfının metodları bu değişkene diledikleri gibi erişebilirken, sınıfın dışından bu değişkene erişmek mümkün değil.
Örneğin:

anadol.hız = 5; // bu atamaların hepsi geçersiz
anadol.hız = 200; //aşırı hız
anadol.hız = -100; // geçersiz hız


gibi atamalar yapmak mümkün değil. Böylece hız değişkenini dışarıdan her türlü müdahaleye kapamış olduk. Arabayı ancak hızlan metodu ile birer birer hızlandırabiliyoruz. Yani her şey bizim kontrolümüz altında. Bizim tasarladığımız Araba sınıfından nesne oluşturup kullanacak herkes, nesnemizi bizim istediğimiz gibi kullanmak zorunda. Buna biz kendimiz de dahiliz. Başka bir ifade ile “Benim sınıfım, benim kurallarım”

Set ve Get Metodları

Yukarıda anlatılan sebeplerden dolayı Java programcıları varsayılan (default) olarak her değişkenin private tanımlanması gerektiğini ve bu değişkenlere erişim gerekiyorsa bunun yalnızca set ve get metodları ile sağlanmasını tavsiye ediyorlar. Şimdi sınıfımıza bir değişken daha ekleyelim, değişkenimize erişim sağlayacak set ve get metodlarını yazalım.

public class Araba {
    private int hız; // bu değişken yalnızca sınıf içerisinden görülebilir.
    private String marka;

    public void setMarka(String marka) {
        this.marka = marka;
    }

    public String getMarka() {
        return marka;
    }

    // sınıfın geri kalanı hala burada 
    // . . .
    
}


Bu sefer arabamızın markasını da belirtelim:

        Araba anadol = new Araba();
        anadol.setMarka("Anadol");                
        Araba mercedes = new Araba();
        mercedes.setMarka("Mercedes");
        
        System.out.println("1. Araba:" + anadol.getMarka());
        System.out.println("2. Araba:" + mercedes.getMarka());


Set metodlarının her zaman ilgili değişken ile aynı tipte bir parametre aldığını ve dönüş tipinin genelde void olduğunu, Get metodlarının ise genelde parametre almadığını ve dönüş tipinin her zaman ilgili değişken ile aynı olduğunu unutmayalım.
Dikkat ettiyseniz sınıf metodlarının başında da public anahtar kelimesi mevcut. Elbette buradan metodların da private olabileceği anlamı çıkıyor. Aklınıza dışarıdan erişilemeyecek bir metod ne işe yarar sorusu gelebilir. Ancak unutmayalım ki sadece sınıf içerisinde kullanılacak, yani “sınıf içi hizmet verecek” metodlar da olabilir.
Yukarıdaki yavaşla metodunda hala bir eksik var. Örneğin metod aşağıdaki gibi çağırılsa:

 anadol.yavaşla(-5);


Hız 5 azaltılmak yerine 5 artırılır ki bu da faciaya davetiye çıkarır. O halde girilen fren değerinin geçerli olup olmadığını kontrol eden ve yalnızca sınıf içinde kullanılan küçük bir metod ile bu sorunu ortadan kaldıralım.

public class Araba {
    private int hız; // bu değişken yalnızca sınıf içerisinden görülebilir.
    private String marka;

   //. . .  diğer metodlar
   //ertugruldeniz.com 
    private boolean frenGeçerliMi(int fren){
        if(fren<0)
            return false; //geçersiz fren değeri
        return true;
    }
      
    public void yavaşla(int miktar){
        if (!frenGeçerliMi(miktar))
            return;
        if (miktar < hız)
            hız = hız - miktar;
        else
            hız = 0; //hız en az 0 olabilir
    }
}


frenGeçerliMi(int fren) metodu private olduğundan aşağıdaki gibi bir kod geçersizdir.

anadol.frenGeçerliMi(-10)// bu kod çalışmaz

Nesneleri Yapıcı (Constructor) Metodlar ile ilklendirme (Initialize)

Araba sınıfımız son hali itibariyle epey ilerlemiş olsa da hala eksikler ve tutarsızlıklar mevcut. Örneğin sınıfımızın mevcut hali ile bir araba nesnesini markasını belirtmeden oluşturabilir, verdiğimiz bir markayı daha sonra dilediğimiz gibi değiştirebiliriz. Aşağıdaki koda bir bakalım:

Araba anadol = new Araba();
        anadol.setMarka("Anadol");
        System.out.println("Marka:" + anadol.getMarka());
        anadol.setMarka("Mercedes");
        System.out.println("Marka:" + anadol.getMarka());


Anadol marka oluşturduğumuz arabayı bir satır kod ile Mercedes yaptık. Bir araba nesnesi ilk oluşturulduğu anda markasını belirtmemiz zorunlu olsa, sonra da bu markayı bir daha değiştiremesek ne güzel olurdu değil mi?
Yapıcı (Constructor) metodlar yalnızca nesne oluşturulurken bir defalığına çağrılan özel metodlardır. İsmiyle müsemma bu metod nesne oluşturulurken (construct edilirken veya yapılırken) çağrılır ve o anda yapılması gereken görevleri icra eder. Her zaman yapıcı metod yazmak zorunda değiliz, yukarıdaki gibi yapıcısı olmayan bir sınıfta yazabiliriz.
Şimdi yukarıdaki hayalimizi gerçekleştirecek olan bir yapıcıyı sınıfımıza ekleyelim.

public class Araba {
    private int hız; // bu değişken yalnızca sınıf içerisinden görülebilir.
    private String marka;

    public Araba(String marka) {
        this.marka = marka;
    }
    
    // setMarka() metodu sınıftan çıkarıldı    

    public String getMarka() {
        return marka;
    }

    //. . . 
}


Aşağıdaki geçersiz kodu inceleyelim:

Araba anadol = new Araba(); // geçersiz
      anadol.setMarka("Anadol"); //artık böyle bir metod yok

br> Şimdide geçerli versiyonunu:

Araba anadol = new Araba("Anadol");  // ilk ve son defa nesnenin markası belirlendi
   System.out.println("Marka: " + anadol.getMarka()); // markayı her zaman öğrenebiliriz.


Böylelikle bir araba nesnesi oluştururken marka belirtmek zorundayız ve bu marka bir daha değiştirilemez çünkü setMarka() metodu artık yok. Ama getMarka() metodu ile her zaman arabanın markasını öğrenebiliriz.

This Anahtar Sözcüğü Nedir

Sınıf kodu içerisinde sınıfın kendisini ifade edebilmek için this anahtar sözcüğünü kullanırız. Aşağıdaki kodda Araba sınıfının yapıcısı metodunda marka isimli iki adet değişken var. Bunlardan biri metoda parametre olarak gönderilen String’i diğeri de sınıfın kendi String değişkenini temsil ediyor.

public class Araba {
    private int hız; // bu değişken yalnızca sınıf içerisinden görülebilir.
    private String marka;

    public Araba(String marka) {
        this.marka = marka;
    }
}


Yukarıdaki kodda :

this.marka = marka

yerine

marka = marka

yazsaydık sol taraftaki marka sınıfın değişkeni olan marka mı yoksa parametre olarak gelen marka mı, belirsiz olacaktı. Bu yüzden this sözcüğü ile açıkça sol taraftaki markanın sınıfın bir değişkeni olduğunu belirtmiş olduk. Alternatif olarak aşağıdaki gibi bir yöntem de izlenebilirdi.

public Araba(String m) {
        marka = m;
}

Bu yöntem belirsizliği ortadan kaldırmakla beraber kodun okunurluğu düşürdüğünden pek tercih edilmemektedir. Çünkü genelde sınıf kodları bizim örneklerimizdeki gibi kısa değil oldukça uzun olabilirler. Bu nedenle o uzun kodun bir bölümünde bir metoda bakarken başında this sözcüğü olan her değişkenin yukarıda tanımlanmış olan bir sınıf değişkeni olduğunu kolayca anlayabiliriz. Böylece zaten karmaşık bir iş olan programlamayı daha da karmaşık hale getirmemiş oluruz.
Değişken ve metod (fonkisyon) isimlerini mantıklı ve anlaşılır seçmek, kodu düzenli yazmaya çalışmak, parantezleri alt alta hizalamak vs. hep bu nedenledir aslında.

Bir Sınıf için birden fazla yapıcı metod yazmak

Araba sınıfımıza arabamızın kaç model olduğunu belirten bir değişken daha ekleyelim.

public class Araba {
    private int hız; // bu değişken yalnızca sınıf içerisinden görülebilir.
    private String marka;
    private int yıl;

    public Araba(String marka) {
        this.marka = marka;
    }

    // . . . sınıfın devamı burada
}


Bir araba nesnesi oluştuğunda marka gibi üretim yılının da belirtilmesini istiyoruz. Ancak bunu marka gibi zorunlu tutmak yerine ufak bir esneklik sağlayalım. Eğer üretim yılı belirtilmez ise oluşturulacak araba nesnesini varsayılan olarak 2010 model kabul edelim.
Bunun sınıfa bir yapıcı metod daha ekleyelim. Mevcut yapıcı metod da ise yıl değişkeninin değerini 2010 yapan kodu. Aşağıdaki kodda kalın font ile belirtilmiş değişiklikleri inceleyiniz.

public class Araba {
    private int hız; // bu değişken yalnızca sınıf içerisinden görülebilir.
    private String marka;
    private int yıl;

    public Araba(String marka) {
        this.marka = marka;
        yıl = 2010;
    }

    public Araba(String marka, int yıl) {        
        this.marka = marka;
        this.yıl = yıl;
    }

    
    // . . . sınıfın devamı burada
}


Araba sınıfının farklı yapıcılarıyla iki araba nesnesi oluşturalım.

    Araba anadol = new Araba("Anadol", 1970);
    Araba mercedes = new Araba("Mercedes"); 


anadol isimli araba nesnesi için yeni yazdığımız yapıcı metod çağrılacaktır. mercedes isimli araba nesnesi için ise ilk yazdığımız ve sonradan yaptığımız değişiklik ile yıl değişkenine 2010 değerini atayan yapıcı metod çağrılacaktır. Türkçe konuşmak gerekirse yalnızca marka belirttiğimiz mercedes nesnesinin üretim yılı otomatik olarak 2010 kabul edildi.
Bir sınıf için teorikte istediğimiz kadar yapıcı metod yazabiliriz. Ancak yapıcı metodların parametre listesi birbirinden farklı olmak zorunda. Aşağıdaki gibi iki yapıcı metodun aynı sınıfta bulunması mümkün değil:

        // bu kod geçerli değil

        public Araba(String marka) {
        this.marka = marka;
        yıl = 2010;
    }
    
    public Araba(String str){
        System.out.println("Nesne oluşuyor");
    }


Çünkü aşağıdaki gibi bir nesne oluşumu sırasında bu yapıcılardan hangisinin çağırılacağı belirli değil. Aşağıda String tipinde tek parametre alan Araba yapıcı metodu çağrılıyor ve yukarıdaki her iki metod da String tipinde tek parametre alıyor. Hangisi çağırılacak?

Araba mercedes = new Araba("Mercedes"); 

Yine aşağıdaki gibi iki yapıcıda mümkün değil. Her ne kadar farklı işler yapıyor olsalar da.

public Araba(int hız) {
        this.hız = hız;
    }
    
    public Araba(int yıl) {
        this.yıl = yıl;
    }


Çünkü aşağıdaki gibi bir kullanımda 1999 değeri bir tamsayıdır (int) ve her iki yapıcı da tamsayı tipinde tek parametre almaktadır. Bilgisayarın 1999’un hız değil de yıl olduğunu anlamasını beklemeyin!

Araba mercedes = new Araba(1999); 

Araba sınıfına aşağıdaki gibi yapıcılar eklemek ise mümkündü.

    public Araba() {
        System.out.println("1. yapıcı metod");
    }

    public Araba(int x) {
        System.out.println("2. yapıcı metod");
    }

    public Araba(String marka) {
        System.out.println("3. yapıcı metod");
    }

    public Araba(String marka, int yıl) {
        System.out.println("4. yapıcı metod");
    }


Görüldüğü gibi her bir yapıcı metodun parametre listesi diğerlerinden farklıdır. Bu arada yapıcı metodlara yukarıdaki gibi anlamsız işler de yaptırabiliriz. Örneğin Araba(String marka, int yıl) yapıcısı bu parametreleri hiç kullanmıyor, yalnızca ekrana bir şeyler yazıyor. Bu mantıklı olmasa da mümkün. Araba sınıfımızın yapıcı metdoları yukarıdaki gibi olsaydı ve aşağıdaki gibi 4 Araba nesnesi oluştursaydık:

        Araba doğan = new Araba();
    Araba doğanGörünümlüŞahin = new Araba(20);
    Araba mercedes = new Araba("Mercedes");      
    Araba anadol = new Araba("Anadol", 1970); 


Programın çıktısı aşağıdaki gibi olurdu:

1. yapıcı metod
2. yapıcı metod
3. yapıcı metod
4. yapıcı metod


Oop yazımızın sonuna gelmiş bulunmaktayız arkadaşlar. Yazının pdf halini isteyen olursa herhangi bir sosyal medya hesaplarım üzerinden yazarsanız iletebilirim. Kolay gelsin.

Bu Gönderiyi Paylaş

İçerik Hakkında Yorum Yapın

www.000webhost.com