Anotasyon

Java Dersleri – Erişim Belirleyiciler

Merhaba arkadaşlar,
mobilhanem.com üzerinden anlattığımız/yayınladığımız derslerimize Temel Java Dersleri konu başlığı altında Erişim Belirleyiciler konusu ile devam ediyoruz.

Erişim belirleyicilerin nasıl kullanıldığından bahsetmeden önce clean code yapısını da destekleyecek bir kaç ufak bilgi vermek istiyorum. Aslında bu bilgiler çoğu yazılımcı tarafından zaten biliniyor ve uygulanıyor fakat burada bir kez daha üstünden geçmekte fayda var.

“Java sınıfları değişken tanımlarıyla başlar eğer sınıfımızda bir değişken tanımlayacaksak bu işlem sınıfın en başında yapılır. Değişkenlerin kendi içerisinde tanımlanma sırası da vardır. public static değişkenler önce yazılmalı, private static değişkenler sonra yazılmalıdır. Metotlarda da yine public erişim belirleyicisine sahip metotlar yazılmalı ardından public içerisinde çağrılan private erişim belirleyicisine sahip sınıflar yazılmalıdır. Clean Code ile ilgili güzel bir yazı dizisine buradan ulaşabilirsiniz. Hem bahsetmiş olduğum düzen hakkında hemde daha fazlası hakkında bilgiye ulaşabilirisiniz.”

Erişim Belirleyiciler

Nesne Yönelimli Programlamada erişim belirleyiciler ufak bir yere sahip olsalarda, hatta bir çok derste bahsi geçmesede bence önemli konulardan bir tanesidir. Java’da proje oluştururken paket mantıksal yapıları sınıf bazında ayırmanın yanı sıra paket yapısıyla da ayırmamız mümkündür. Java ile proje geliştirirken paket yapısı olmazsa olmaz denilebilir. Paket yapısı projenin geliştirildiği web sitesi veya firmanın domain adını içerecek şekilde tersten oluşturulur. Ne demek istediğimi aşağıdaki örnekte daha iyi anlayacaksınız.

package com.mobilhanem.temeljavadersleri.nesneyonelimliprogramlama

Biz bu dersimiz altında bir proje geliştiriyor olsak paket yapısının yukarıdaki gibi olması gerekmektedir (şart değil). Tamamen yazılım ekibine kalmış bir seçimdir ve tüm ekibin en iyi şekilde anlayacağı bir paket yapısı kurularak kullanılır. Özellikle büyük projelerde karmaşıklığı ortadan kaldırdığı gibi kolaylıkta sağlar. Paket yapısında esas amaç mantıksal birlikteliği olan sınıfları aynı paket altında toplamaktır. Paket yapısıyla ilgili bu uzun detaydan sonra gelelim erişim belirleyicilere. Paket yapıları kurulduktan, sınıflar bu paketler altında yerlerini aldıktan, ve sınıflar içerisinde farklı görevlere sahip metotlar oluşturulduktan sonra sınıfların farklı sınıflardaki metotlara erişim sağlaması gerekmekte veya bir sınıftaki özel bir metoda başka hiç bir sınıfın erişememesi gerekmektedir. İşte bu gibi durumları belirlediğimiz yapı Erişim belirleyicilerdir. Java’da erişim belirleyiciler 4 çeşittir;

  1. public
  2. protected
  3. private
  4. friendly(erişim belirleyici yok)

Örnekli anlatımlara geçmeden önce Java’nın sitesinde yayınlanan aşağıdaki tabloyu inceleyelim.

Modifier
Class
Package
Subclass
World
public
Y
Y
Y
Y
protected
Y
Y
Y
N
no modifier
Y
Y
N
N
private
Y
N
N
N

Kısaca tabloyu anlatıp ardından örneklere başlayalım. Tabloda public erişim belirleyicinin her yerden erişilebileceği söylenmekte. protected erişim belirleyici sınıf, paket ve altsınıflar tarafından erişilebilir. friendly yani bir erişim belirleyici kullanmadan yaptığımız tanımlamalar sınıf ve paket içerisinden erişilebilir. private ise sadece sınıf içerisinden erişilebilir.

Örnek

Şimdi ufak ama bugüne kadar yaptığımız en büyük örneğe başlayalım. Öncelikle bir OzelArac sınıfı yaratalım ve bu OzelArac’ın bir kullanıcısı olması için AracKullanicisi sınıfını yaratalım. Bir de bu OzelArac’a bir Yolcu bindirelim. Sonrasında yukarıda bahsettiğimiz erişim belirleyicilerle kimin neler yapacağını belirleyelim.

OzelArac.java

package com.mobilhanem.temeljavadersleri.oop.kisiselarac;

/**
 *
 * @author ErenBasaran
 *         Created on 30/07/2017
 */
public class OzelArac {

    private boolean camlarAcilabilir;
    private boolean kapilarAcilabilir;

    public OzelArac() {
        motorDegerleriniKontrolEt();
    }

    private void motorDegerleriniKontrolEt() {
        System.out.println("Arabanın motor değerlerinin kontrol edilmesi tamamlandı.");
    }


    protected boolean arabayiCalistir() {
        System.out.println("Arabayı çalıştırmak için gerekli tetikleme yapıldı.");
        System.out.println("Araba başarılı bir şekilde çalıştırıldı.");

        return true;
    }

    public boolean isCamlarAcilabilir() {
        return camlarAcilabilir;
    }

    protected void setCamlarAcilabilir(boolean camlarAcilabilir) {
        this.camlarAcilabilir = camlarAcilabilir;
    }

    public boolean isKapilarAcilabilir() {
        return kapilarAcilabilir;
    }

    protected void setKapilarAcilabilir(boolean kapilarAcilabilir) {
        this.kapilarAcilabilir = kapilarAcilabilir;
    }
}

Bu sınıfta ne yaptığımı hemen anlatayım. Öncelikle camlarAcilabilir ve kapilarAcilabilir olarak iki tane boolean veri tipine sahip değişken tanımladım. Bu değişkenlere başka sınıflardan erişim olmasın diye erişim belirleyici olarak private tanımladım.

Sadece OzelArac’ın kendisini ilgilendiren motorDegerleriniKontrolEt adında bir metot tanımladım ve bu metodun erişim belirleyicisini de private olarak tanımladım. Çünkü bunu OzelArac kendi içerisinde yapacak ve AracKullanicisi’na sadece bilgi verecek. Bu metodu constructor içerisinde tetikleyerek OzelArac nesnesi her oluştuğunda motor kontrollerinin yapılmasını sağladım.

AracKullanicisi sınıfını OzelArac sınıfı ile aynı paket içinde oluşturacağım için , arabayiCalistir metodunun erişim belirleyicisini protected olarak belirledim. Ardından aynı mantıkla boolean veri tipine sahip değişkenlerimin değerlerini sadece AracKullanicisi değiştirebileceği için setter metotlarını protected tanımlarken getter metotlarına herkes erişebilsin diye public olarak tanımladım. Şimdi AracKullanicisi sınıfı nasıl olmuş onu inceleyelim.

AracKullanicisi.java

package com.mobilhanem.temeljavadersleri.oop.kisiselarac;

import com.mobilhanem.temeljavadersleri.oop.kisiselarac.yolcu.Yolcu;

/**
 *
 * @author ErenBasaran
 *         Created on 30/07/2017
 */
public class AracKullanicisi {

    public static void main(String[] args) {

        /**
         * OzelArac sınıfından bir nesne olusturuldu.
         */
        OzelArac ozelArac = new OzelArac();

        /**
         * protected erişim tipi ile tanımlanan metot aynı paket içinden çağrıldı.
         */
        ozelArac.arabayiCalistir();

        /**
         * setter yapısı protected olarak tanımlanan camlarAcilabilir değişkeni aynı paket içindeki
         * AracKullainicisi tarafından setlenebildi.
         */
        ozelArac.setCamlarAcilabilir(true);

        /**
         * setter yapısı protected olarak tanımlanan kapilarAcilabilir değişkeni aynı paket içindeki
         * AracKullainicisi tarafından setlenebildi.
         */
        ozelArac.setKapilarAcilabilir(false);

        Yolcu yolcu = new Yolcu();
        System.out.println("If-Else yapısı ile yaz:");
        yolcu.yolcununYapabilecekleriniYazdir(ozelArac);
        System.out.println("? : yapısı ile yaz:");
        yolcu.yolcununYapabilecekleriniYazdir1(ozelArac);

    }

}

AracKullanicisi sınıfı benim ana sınıfım yapıyı buradan çalıştırıyorum, bu sebeple AracKullanicisi sınıfı içerisinde main metodum var. Bu main metot içerisinde bir tane OzelArac nesnesi tanımlıyorum ve arabayı çalıştırmak için arabayiCalistir metodunu tetikliyorum. Arabayı çalıştırdıktan sonra araç kullanıcısı olarak yolcuları düşünüyorum ve onlar için ufak bazı önlemler alıyorum. Sadece OzelArac sınıfı ve AracKullanicisi sınıflarından erişim sağlanabilecek setCamlarAcilabilir ve setKapilarAcilabilir metotlarına değer atıyorum. Ardından aşağıda görebileceğiniz Yolcu sınıfından bir nesne oluşturuyor ve yolcuların yapabileceklerini yazdırıyorum.

Yolcu.java

package com.mobilhanem.temeljavadersleri.oop.kisiselarac.yolcu;

import com.mobilhanem.temeljavadersleri.oop.kisiselarac.OzelArac;

/**
 *
 * @author ErenBasaran
 *         Created on 30/07/2017
 */
public class Yolcu {

    //Diğer sınıflardan erişilemeyecek sadece bu sınıf içerisinden erişilebilen değişkenler.
    private String yolcuCamlariAcabilir = "Yolcu camları açabilir";
    private String yolcuCamlariAcamaz = "Yolcu camlari açamaz!";
    private String yolcuKapilariAcabilir = "Yolcu kapıları açabilir";
    private String yolcuKapilariAcamaz = "Yolcu kapıları açamaz!";

    /**
     * Yolcunun yapabileceklerinin AracKullanicisi sınıfında belirlenen yapıya göre tanımlandığı
     * detayları yazdırır.
     */
    public void yolcununYapabilecekleriniYazdir(OzelArac ozelArac) {
        if(ozelArac.isCamlarAcilabilir()) {
            System.out.println(yolcuCamlariAcabilir);
        } else {
            System.out.println(yolcuCamlariAcamaz);
        }

        if(ozelArac.isKapilarAcilabilir()) {
            System.out.println(yolcuKapilariAcabilir);
        } else {
            System.out.println(yolcuKapilariAcamaz);
        }
    }

    /**
     * yolcununYapabilecekleriniYazdir metodu ile aynı işlemi yapmakta olan bu metot
     * if-else kullanımının farklı bir versiyonudur.
     */
    public void yolcununYapabilecekleriniYazdir1(OzelArac ozelArac) {
        System.out.println(ozelArac.isCamlarAcilabilir() ? yolcuCamlariAcabilir : yolcuCamlariAcamaz);
        System.out.println(ozelArac.isKapilarAcilabilir() ? yolcuKapilariAcabilir : yolcuKapilariAcamaz);
    }

}

Burada ilk dikkat etmemiz gereken, OzelArac ve AracKullanicisi sınıflarının paketleri aynı iken Yolcu sınıfının paketi farklıdır. Bu sınıf içerisinde de diğer sınıfları ilgilendirmeyen yolcunun neler yapabileceği hakkında bilgi verecek değişkenler tanımladım. Bu değişkenlere getter ve setter yazmadım ve erişim belirleyici olarak private kullandım. Bu demek oluyor ki bu değişkenlere bu sınıf haricinde hiçbir sınıftan erişim sağlanamaz (okunamaz ve değiştirilemez). yolcununYapabilecekleriniYazdir metodunda erişim belirleyici olarak public kullandım çünkü AracKullanicisi sınıfı ile farklı paketlerde oldukları için AracKullanicisi sınıfından erişilebilmeli.

Bonus

Burada ekstra bilgi olarak if-else ve ? (conditional operator) yapısını kullanarak iki farklı metot oluşturdum. İkinci metodun kullanımındaki sadelik ve basitlik gözden kaçmıyor. Bu yapı şu şekildedir;

booleanDeger ? dogruysaBunuYap() : yanlissaBunuYap();

Sonuç

Nesne Yönelimli Programlama Java’da en önemli konulardan birisidir. Bu dersimizde Nesne Yönelim Programlama da işimize yarayacak olmazsa olmaz erişim belirleyiciler’inden (public, protected ,private ,friendly) bahsettik. Bir sonraki dersimizde Nesne Yönelimli Programlama’nın temel yapılarından bahsedecek ve daha derinlere ineceğiz.

Yukarıdaki örneğin tamamına mobilhanem GitHub hesabından erişebilirsiniz. Projenin GitHub üzerinde tam linki için buraya tıklayabilirsiniz.

Konuyla ilgili yorumlarınızı konu altından yapabilirsiniz, ayrıca sorularınızı Mobilhanem Soru&Cevap bölümünden sorabilirsiniz.

Tüm Temel Java Dersleri için tıklayınız..

63

Eren Başaran

Software Developer
Mobilhanem Yazarı

2 Yorum

Haftalık Bülten

Mobilhanem'de yayınlanan dersleri haftalık mail almak ister misiniz?