Yücel Alkan

PHP OOP Access Modifiers (Erişim Türleri)

Merhaba. Bu yazımda Object Oriented Programmin yapısında kullanılan Access Modifiers yani erişim türlerinden bahsedeceğim. Access Modifiers kullanarak class yapısı içinde yer alan üyelerin yani değişken ve fonksiyonların gizlilik derecesini belirtebiliyoruz. Yani daha açık bir ifadeyle söylemek gerekirse; Access Modifiers yardımıyla class içindeki değişken ve fonksiyonlara hangi durumlarda ve nerelerden erişim sağlanabileceğini ayarlayabiliyoruz. 

PHP OOP yapısı içinde kullanılan 3 farklı erişim türü vardır. 

  1. Public
  2. Private
  3. Protected

Bunlarla birlikte, bu yazıda default ve static yapılarından da bahsetmek istiyorum. Default ile başlayalım.

Default

Aslında PHP içinde default adında bir erişim türü bulunmuyor. Class içerisinde yer alan bir fonksiyonun erişim türünü belirtmezseniz default olarak public yapısında tanımlanmış olur. Ancak değişkenlerde böyle bir kullanım türü bulunmuyor. Yani değişkenlerin başına mutlaka bir erişim türü yazmak zorundasınız. 

class Calisan
{
    public function maasHesapla()
    {
        // İşlemler
    }

    function zamYap()
    {
        // İşlemler
    }
}

Yukarıdaki örnekte Calisan adında bir class oluşturup içerisine iki tane fonksiyon tanımı yaptık. Dikkat ederseniz maasHesapla() fonksiyonunun başında public ifadesi varken, zamYap() fonksiyonunun başında herhangi bir erişim türü bulunmuyor. İşte zamYap() şeklinde bir fonksiyon tanımı yaparsanız, yani başına herhangi bir erişim türü belirtmezseniz, varsayılan olarak public yapısında tanımlanmış olacaktır. Yani özetle hem maasHesapla() hem de zamYap() fonksiyonlarının ikisinin de erişim türü public'dir. 

1. Public

Class içerisinde public olarak tanımlanan bir değişken veya fonksiyona her yerden erişim sağlanabilir. Yani public olarak tanımlanan bir değişken veya fonksiyona; hem oluşturulan nesne üzerinden hem de bu class'ı miras alarak oluşturulan tüm class yapıları üzeirnden doğrudan erişim sağlanabilir. Miras alma konusunu daha detaylı olarak ayrı bir yazımda anlatacağım ancak private ve protected yapısını açıklarken değinmiş olacağım. 

class Calisan
{
    public $adSoyad;
    public $maas; 

    public function zamYap($miktar)
    {
        $this->maas += $miktar;
    }
}

$isci = new Calisan();
$isci->adSoyad = "Serkan Aykut";
$isci->maas = 2400;

$isci->zamYap(200);

Yukarıdaki örnekte tüm değişken ve fonksiyonlar public olarak tanımlanmıştır. Yani bu üyelere her yerden erişim sağlama imkânım bulunuyor. 

Örnekte de görüldüğü gibi $isci adındaki nesne üzerinden Calisan class'ının hem adSoyad ve maas değişkenlerine, hem de zamYap() adındaki fonksiyonuna doğrudan erişim sağladım. 

2. Private

Private yapısında tanımlanan bir değişken veya fonksiyona sadece class içerisinden erişim sağlanabilir. Yani private olarak tanımlanan bir üyeye, nesne üzerinden doğrudan erişim sağlayamazsınız. Ayrıca bu class'ı miras alaraka üretilen class'lar üzerinden de yine private olarak tanımlanan üyeye erişim sağlanamaz. 

Aşağıdaki basit örneği inceleyelim.

class Calisan 
{
    public $adSoyad;
    private $maas; 
}

$isci = new Calisan();
$isci->adSoyad = "Mehmet Kaya";

$isci->maas = 2400;

Calisan adında bir class oluşturduktan sonra içerisine public türünden $adSoyad değişkeni tanımladım. Bu değişken public olduğu için her yerden erişim sağlayabilirim. Ancak $maas değişkenini private yapısında tanımladım. 

Ardından $isci adında bir nesne üretip adSoyad değerini atadım. Buraya kadar sıkıntı yok. Bir sonraki adımda $isci nesnesinin maaş değişkenine değer atadım. İşte $maas değişkeni private olarak tanımlandığı için class dışından doğrudan erişim mümkün değildir. Bu sayfayı çalıştırdığım zaman aşağıdaki gibi bir hatayla karşılaşacağım. 

Fatal error: Uncaught Error: Cannot access private property Calisan::$maas...

Bu hata, Calisan adındaki class'ın $maaş özelliği private olduğu için erişim sağlanamadığını belirtmektedir. 

Private olarak tanımlanan bir değişkene veya fonksiyona doğrudan erişim mümkün olmadığından, bu değişkenlere değer atamak veya bu değişkenlerdeki değerleri okumak için set ve get adında public türünden fonksiyonlar üretilir. 

class Calisan 
{
    public $adSoyad;
    private $maas; 

    public function setMaas($deger)
    {
        $this->maas = $deger;
    }

    public function getMaas()
    {
        return $this->maas;
    }

}

$isci = new Calisan();
$isci->adSoyad = "Mehmet Kaya";

$isci->setMaas(2400);

echo $isci->getMaas();

Private olan $maas değişkenine doğrudan erişim sağlayamadığım için maaş değerini atayabilmek için setMaas(), maaş değerini öğrenebilmek, alabilmek içinse getMaas() adında iki tane public türünden fonksiyon oluşturdum. Bu iki fonksiyon yardımıyla maaş değeri üzerinde işlem yapabilirim. 

Aklınıza şu soru gelmiş olabilir: Neden yolu bu kadar uzattık, doğrudan maaş değerini atasaydık ya? Çünkü OOP yapısına göre class'lar bağımsız yapıda olsa da diğer class'larla birlikte çalışmaktadır. Erişim türlerini doğru bir şekilde seçmezseniz sistemsel hatalar meydana gelebilir. Mesela; bir banka sistemi düşünün. Bu sistemde bir müşterinin bankadaki bakiyesi yani parasının miktarını public olarak tanımlarsanız, bu değişkene her yerden erişim sağlanabileceği için bakiye değişkeni her ortamdan değiştirilebilir. Bu da istenmeyen sonuçlar doğurabilir. Yani özetle her ortamdan erişilmesini istemediğiniz, gizli kalmasını ve erişim sağlanacak ortamları kendiniz belirlemek istediğiniz değişken ve fonksiyonlar için private yapısını kullanabilirsiniz. 

Gelelim private değişken ve fonksiyonların, miras alma işlemi sonrasındaki durumlarına. Private olarak tanımlanan bir değişken veya fonksiyona, miras alma sonucu oluşturulan class üzerinden erişim sağlanamaz. Aşağıdaki örneğimizi inceleyelim. 

<?php 

class Calisan
{
    public $adSoyad;
    private $maas;

    public function setMaas($miktar)
    {
        return $this->maas = $miktar;
    }

    private function zamYap($miktar)
    {
        $this->maas += $miktar;
    }
}

class Muhendis extends Calisan 
{
    public $brans; 

    public function veriAyarla()
    {
        $this->adSoyad = "Mehmet Kaya";     // Erişim sağlanır.
        $this->setMaas(4500);               // Erişim Sağlanır

        $this->zamYap(500);                 // Erişim Sağlanamaz. Çünkü private


    }
}

$muhendis = new Muhendis();
$muhendis->veriAyarla();

Miras alma işlemlerine detaylı olarak değineceğim İnşallah. Burada sadece private yapısını açıklamaya çalışıyorum. Örnekte Muhendis adlı class, Calisan adlı class miras alınarak oluşturulmuştur. Miras alma işlemi sonucu, miras alınan class içerisindeki public türünden tüm değişken ve fonksiyonlar, oluşturulan class içerisinde tanımlanmış olur. Ancak private türünden oluşan 

Yukarıdaki örneğe göre $muhendis nesnesi ile Muhendis sınıfına ait veriAyarla() fonksiyonunu çağırdım. Bu fonksiyon içerisindeki adSoyad değişkeni ile setMaas() ve zamYap() fonksiyonları Calisan sınıfında bulunan üyelerdir. İşte bu üyelerden adSoyad değişkenine ve setMaas() fonksiyonuna erişim sağlamak mümkündür. Ancak zamYap() fonksiyonu private olduğu için erişim sağlanamaz. 

Özetle, private türünden bir değişken veya fonksiyona sadece o class içerisinden erişim sağlanabilir. O class ile üretilen nesne veya o claass miras alınarak oluşturulan class içinde doğruran erişim sağlanamaz. 

3. Protected

Protected olarak tanımlanan değişken veya fonksiyona class içinde veya bu class miras alınarak türetilen class'lardan erişim sağlanabilir. Oluşturulan bir nesne üzerinden protected üyelere erişim sağlanamaz. 

Private ile protected'ın farkı şudur: Private olarak tanımlanan bir değişken veya fonksiyona, class dışından erişim sağlanamazken; protected olarak tanımlanan değişken veya fonksiyona o class miras alınarak üretilen class içerisinden erişim sağlanabilir. 

Yine örnek üzerinden gidelim. 

class Calisan
{
    public $adSoyad;
    public $maas;

    protected function zamYap($miktar)
    {
        $this->maas += $miktar;
    }
}

$isci = new Calisan();
$isci->maas = 2400;

$isci->zamYap(200);         // Erişim sağlanamaz. Çünkü protected tanımlı bir fonksiyon

Yukarıdaki örneği incelediğimiz zaman $adSoyad ve $maas değişkenlerine public olduğu için doğrudan erişim sağlandığını göreceğiz. Ancak zamYap() fonksiyonuna nesne üzerinden doğrudan erişim sağlamaya çalıştığımız zaman aşağıdaki hatayı verecektir. Çünkü topkı private'te olduğu gibi protected olarak tanımlanan bir değişken veya fonksiyona nesne üzerinden doğrudan erişim sağlanamaz. 

Fatal error: Uncaught Error: Call to protected method Calisan::zamYap() from 

Bir de miras alma yoluyla class üretelim ve bu class üzerinden protected olarak tanımlanan bir fonksiyona erişmeye çalışalım. 

class Calisan
{
    public $adSoyad;
    private $maas;

    public function setMaas($miktar)
    {
        return $this->maas = $miktar;
    }

    protected function zamYap($miktar)
    {
        $this->maas += $miktar;
    }
}

class Muhendis extends Calisan 
{
    public $brans; 

    public function veriAyarla()
    {
        $this->adSoyad = "Mehmet Kaya";     // Erişim sağlanır.
        $this->setMaas(4500);               // Erişim Sağlanır

        $this->zamYap(500);                 
        // Erişim sağlanır. Private olsaydı hata verecekti ancak protected olduğu için çalışır.

    }
}

$muhendis = new Muhendis();
$muhendis->veriAyarla();

Bu örneğin aynısını yukarıda private'i incelerken yapmıştık. Ancak küçük bir değişiklik yaptık. zamYap() fonksiyonunu private değil de protected olarak tanımladık. zamYap() fonksiyonu protected olarak tanımlandığı için hem Calisan isimli class üzerinden hem de bu class'ı miras alarak oluşturduğum Muhendis class'ı içinde erişim mümkündür. İşte private ile protected arasındaki en büyük daha doğrusu ince fark burada. 

Access Modifiers yani erişim düzenleyicileri bir tablo ile özetleyelim.

Access Modifier Sınıf İçi Sınıf Dışı Türetme (Miras)
Public
Protected x
Private x x

Static Yapısı

Static ile tanımlanan değişken ve fonksiyonlara erişim sağlamak için yeni bir instance yani nesne oluşturmaya gerek yoktur. Normalde bir class yapısının içerisinde yer alan değişken ve fonksiyonlara erişim için new anahtar kelimesiyle yeni bir nesne üretilmesi gerekiyor. Ancak static anahtar kelimesiyle tanımlanmış değişken ve fonksiyonlara yeni bir nesne üretmeden doğrudan erişim mümkündür. 

class Araclar
{
    static $pi = 3.14;

    static function sayiUret()
    {
        echo rand(1000,9999);
    }
}

echo Araclar::$pi;
Araclar::sayiUret();

Yukarıdaki örnekte Araclar adında bir class oluşturup içinde iki tane üye oluşturdum. Bu üyeleri yani değişken ve fonksiyonu static yapısıyla tanıttım. Bu üyeleri kullanmak içinse new ahatar kelimesiyle yeni bir nesne üretmedim. İşte static ifadesiyle oluşturulan değişken ve fonksiyonlara bu şekilde doğrudan class adını yazarark erişmek mümkündür. 

Küçük bir not daha düşelim. Normalde class içerisindeki değişkenlere erişim sağlanırken $ işareti kullanılmaz. Ancak static yapıdaki değişkenlere erişim için $ işareti konulmak zorundadır. 

Konuyla ilgili videoya aşağıdan ulaşabilirsiniz.



Soru ve görüşlerinizi yorum olarak belirtebilirsiniz. Hayırlı çalışmalar dilerim.

Yorumlar
Bu içeriğe henüz yorum yapılmamıştır. İlk yorum yapan siz olun!
Yorum Yapın