PHP – Late Static Binding (Self ve Static Farkı)

Bu yazıda PHP’de self ve static anahtar kelimelerinin çalışma şekillerinden bahsedeceğim.

Öncelikle şunu belirteyim static anahtar kelimesi PHP 5.3.0’dan sonraki sürümlerde çalışır.

Self ve Static’in Aralarındaki Fark?

self, static öğelere (metod, değişken) erişmek için kullanılır.
static öğelelere erişmek için yine static anahtar kelimesi de kullanılabilir.

Ama aralarında önemli bir fark vardır. Örneğin: X sınıfı var içinde Z public static metodu var. Y sınıfı da X’den türeme.

self bulunduğu class’da bulunan metodun barındırdığı değeri verirken static ise türetilen (extend edilen) sınıftaki metodun değerini verir.

Static anahtar kelimesinin bu çalışma mantığı Late Static Binding olarak da adlandırılır.

Örnek kod:

<?php

class X {
    public static function Z(){
        return "X çağırıldı\n";
    }

    public function getSelfZ(){
        echo self::Z(); // X sinifindaki deger doner
    }
    
    public function getStaticZ(){
        echo static::Z();//turetilen (extend edilen yani Y sinifi) siniftaki deger doner
    }
}

class Y extends X {
    public static function Z(){
        return "Y çağırıldı\n";
    }
}

$a = new Y();
$a->getSelfZ();
$a->getStaticZ();

Not: Bu kodu PHP 5.2.x’de çalıştırırsanız 13. satırda hata alacaksınız.

 
31 Kudos
Don't move
  1. Ömer Fadıl USTA

    //ana sınıfda ki deger doner.
    kısmına aslında
    //mevcut/geçerli sınıftaki değer döner
    desek daha anlaşılır olacaktır diye düşünüyorum çünkü ana sınıf diye söylendiğinde bunların doğduğu yani extend edildiği sınıf olarak da akla gelebilir

    • Dediğinizi tam anlayamadım kusura bakmayın lütfen. getSelfZ() metodunu çağırınca “X çağırıldı” değilde “Y çağırıldı” mı yazar diyorsunuz?

      • Ömer Fadıl USTA

        Yok çıktıda değil yorumda ufak bir yanlış anlaşılabilme ihtimali olduğunu belirttim.
        Orada ana sınıfda ki deger doner
        yazdığınız satırda ana sınıf diyince insanlar ana sınıf kavramını mevcut sınıf değilde miras Veren olacağını düşünebilirler.
        Kısaca //ana sınıfda ki deger doner.
        yerine // X sınıfındaki değer döner veya mevcut sınıftaki değer döner yazılması daha uygun olacaktı diye düşünmüştüm

        • ana sınıftan kastım zaten X sınıfı.

          “X sınıfındaki değer döner” daha açıklayıcı madem öyle yaptım.

          Sizin dediğinize göre “mevcut sınıftaki değer döner” açıklaması da pek açıklayıcı görünmüyor.

  2. Merhaba,eline sağlık.Sayende static kelimesinin böyle işler yaptığını öğrendim ve kafamda soru işaretleri uçuşmaya başladı :),parent class dan child classdaki bir methodu çağırmak nekadar doğru olur? yani parent class bir nevi child class’a bağımlı oluyor bu şekilde.

    • Ömer Fadıl USTA

      Aslında static bir methodun asıl kullanım amacı ilgili class’tan bir instance oluşturmadan doğrudan çağırılabilmesidir.

      Yani Diyelim elinde Okul diye bir sinif mevcut sen
      $a = new Okul();
      $a->ogrenciSayisi();
      normalde demen gerekir yani Okuldan bir instance oluşturman gerekir ama ogrenciSayisi methodu eğer static olarak belirtmiş isen hiç new Okul()
      demek zorunda kalmadan doğrudan Okul::ogrenciSayisi();
      diyebilirsin.

      Diğer programlama dillerinden örnek vermem gerekirse
      java için örneğin JOptionPane.showMessageDialog(null, “Merhaba.”);
      veya
      c# için :
      MessageBox.Show(“Merhaba.”);
      bu iki örnekte mesela showMessageDialog ve Show methodları static tanımlandığı için JOptionPane ve MessageBox sınıflarından instance üretmene gerek kalmadan doğrudan dahili methodu çağırabiliyorsun.

      Soruna gelince static method veya değişkenler instancelardan bağımsız ve adından anlaşılacağı gibi statiktirler yani düşündüğün gibi bellekte alt/üst nesne için instance oluşturulmaz sadece o kodun kopyası belleğe alınır.

    • Feyyaz Esatoğlu

      Merhaba,

      aslında çok pratik durumlar oluşturabiliyor ama oop’ye hiyerarşik olarak parent – child olarak baktığında evet biraz garip duruyor. Mesela birtane Application sınıfın olsun parent, ve ChildApplication0 … ChildApplication{N} kadar da Application sınıfından türetilecek sınıfların olsun Child. ChildApplication sınıflarında birbiriyle aynı yada birbirine yakın olan X tane task için X tane method oluşturman gerekecek. Yani her bir child parent’in ilgili fonksiyonunu çağırıp ona iş yaptıracak buda N tane sınıf için N kere aynı methodu ayrı ayrı yazmak demek ve her bir sınıf için X tane aynı görev demek buda N.X kere tekrar yazım demek, ama late static binding sana bu işlerin tamamını N.X yerine X kere yazarak yapabileceğini vaad ediyor. Çok büyük çıldırmış gibi child class oluşturduğun işlerde kesinlikle OOP’yi destekliyor ve çift yönlü çalışır duruma getiriyor. Bunun yanında Parent Class Child Class’a kesinlikle bağımlı olmuyor zaten tasarımda parent’in child’in metodunu kullanacağı düşünülüyorsa default olarak parent içerisinde de aynı isimde metod bulunuyor örneğin dışarıya bu metod sınıf türetilmeden kullanılamaz diye bir exception throw edilebilir. Eğer child içerisinde böyle bir method yoksa otomatik olarak static self gibi çalışacaktır. Zaten Adil’de makalede belirtmiş. Güzel Makale teşekkürler.

  3. güzel anlatim tesekkürler.

Yorum Yap


Not - Bunları KullanabilirsinizHTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>