PHP/Sınıflar

Vikikitap, özgür kütüphane
< PHP

Sınıflar[değiştir]

Sınıflar class anahtar sözcüğü ile tanımlanır. Sınıflar değişken ve fonksiyonları içerir. Sınıf elemanı olan değişkenler genellikle özellik veya öznitelik, sınıf elemanı olan fonksiyonlar ise metot veya yöntem olarak adlandırılır.

<?php
class IlkSinif
{
    public $IlkOzellik;

    public function IlkMetot()
    {
    }
}
?>

Yukarıda, IlkOzellik adında bir özellik ve IlkMetot adında bir metot içeren IlkSinif isimli bir sınıf tanımlandı.

Sınıf içinde özellik ve metotlara erişmek[değiştir]

$this değişkeni, sınıf içinde, tanımlı özelliklere ve metotlara erişmeyi sağlar.

<?php
class IlkSinif
{
    public $IlkOzellik = "Bir değer";

    public function IlkMetot()
    {
        echo $this->IlkOzellik; // $IlkOzellik özelliğine erişiliyor
    }
    
    public function IkinciMetot()
    {
        $this->IlkMetot(); // IlkMetot metodu çağrılıyor
    }
}
?>

Örnekte de görüldüğü gibi $this değişkenine ek olarak -> işaretinden sonra erişilmek istenen özelliğin veya metodun ismi yazılıyor.

Nesne yaratmak[değiştir]

Bir sınıftan nesne yaratmak için new anahtar sözcüğü kullanılır. Bu sayede, sınıfın bir örneği oluşturulmuş olur.

<?php
class IlkSinif
{
    public $IlkOzellik = "Bir değer";

    public function IlkMetot()
    {
        echo $this->IlkOzellik;
    }
}
$nesne = new IlkSinif();
?>

Son satırda, IlkSinif sınıfının $nesne adında bir örneği oluşturuldu. Artık bu nesne üzerinden sınıfın özellik ve metotlarına sınıf dışından erişebiliriz. Şimdi, oluşturduğumuz nesneyi kullanarak IlkMetot metoduna sınıf dışından erişelim. Yani fonksiyonlarda olduğu gibi çağıralım ve çalışmasını sağlayalım.

<?php
class IlkSinif
{
    public $IlkOzellik = "Bir değer";

    public function IlkMetot()
    {
        echo $this->IlkOzellik;
    }
}
$nesne = new IlkSinif();
$nesne->IlkMetot();
?>

Aynen $this değişkeninde olduğu gibi $nesne nesnesine ek olarak -> işaretinden sonra IlkMetot metodunun ismi yazılarak ilgili metot çağrıldı. Tahmin edebileceğiniz gibi bu metodun görevi, sınıf içinde tanımlı IlkOzellik özelliğinin değerini -yani Bir değer ifadesini- çıktılamaktır.

Şimdi, örnek olması açısından bir öğretim üyesinin isim, soyisim ve unvan bilgileriyle işlemler yapan basit bir sınıf tanımlayalım.

<?php
class OgretimUyesi
{
    public $Unvan;
    public $Isim;
    public $Soyisim;

    public function Kaydet($unvan, $isim, $soyisim)
    {
        $this->Unvan = $unvan;
        $this->Isim = $isim;
        $this->Soyisim = $soyisim;
    }

    public function Getir()
    {
        echo "{$this->Unvan} {$this->Isim} {$this->Soyisim}";
    }
}
$uye = new OgretimUyesi();
$uye->Kaydet("Doç. Dr.", "Sinan", "Sağıroğlu");
$uye->Getir();
?>

Şimdi bu örneği açıklayalım. OgretimUyesi isimli bir sınıf tanımladık. Bu sınıfın Unvan, Isım ve Soyisim adında üç adet özelliği var. Aynı zamanda da Kaydet ve Getir isimli iki metoda sahip. Kaydet metodu, kendisine parametre olarak gönderilen değerleri $this değişkenini kullanarak sırasıyla Unvan, Isim ve Soyisim özelliklerine atıyor. Getir metodu ise sınıfın özelliklerini ekrana çıktılıyor. Sınıfımızı tanımladıktan sonra, bu sınıftan uye adında bir nesne yarattık. Bu nesne üzerinden sınıfın Kaydet metodunu, gerekli parametre değerlerini göndererek çağırdık. Kaydet metodu gönderdiğimiz değerleri, uye nesnesi için sınıfın özelliklerine atadı. Son olarak ise Getir metodunu çağırdık ve özelliklerin değerlerini çıktıladık.

Getir metodunu çağırmak yerine, uye nesnesini kullanarak, sınıf özelliklerine de erişebilirdik. Yani:

<?php
class OgretimUyesi
{
    public $Unvan;
    public $Isim;
    public $Soyisim;

    public function Kaydet($unvan, $isim, $soyisim)
    {
        $this->Unvan = $unvan;
        $this->Isim = $isim;
        $this->Soyisim = $soyisim;
    }

    public function Getir()
    {
        echo "{$this->Unvan} {$this->Isim} {$this->Soyisim}";
    }
}
$uye = new OgretimUyesi();
$uye->Kaydet("Doç. Dr.", "Sinan", "Sağıroğlu");
echo "{$uye->Unvan} {$uye->Isim} {$uye->Soyisim}";
?>

Görüldüğü gibi burada Getir metodunu kullanmak yerine, sınıf özelliklerine direkt olarak eriştik.

Başka bir öğretim üyesi daha kaydedelim:

<?php
class OgretimUyesi
{
    public $Unvan;
    public $Isim;
    public $Soyisim;

    public function Kaydet($unvan, $isim, $soyisim)
    {
        $this->Unvan = $unvan;
        $this->Isim = $isim;
        $this->Soyisim = $soyisim;
    }

    public function Getir()
    {
        echo "{$this->Unvan} {$this->Isim} {$this->Soyisim}<br>";
    }
}
$uye1 = new OgretimUyesi();
$uye2 = new OgretimUyesi();
$uye1->Kaydet("Doç. Dr.", "Sinan", "Sağıroğlu");
$uye2->Kaydet("Prof. Dr.", "Fahrettin", "Topak");
$uye1->Getir();
$uye2->Getir();
?>

uye1 ve uye2 adlarında iki nesne yarattık. Her nesne için ayrı ayrı Kaydet ve Getir metotlarını kullandık. Her nesne için sınıf özelliklerinin farklı değerler tuttuğuna dikkat edin. Aşağıdaki örneği inceleyiniz.

<?php
class OgretimUyesi
{
    public $Unvan;
    public $Isim;
    public $Soyisim;

    public function Kaydet($unvan, $isim, $soyisim)
    {
        $this->Unvan = $unvan;
        $this->Isim = $isim;
        $this->Soyisim = $soyisim;
    }

    public function Getir()
    {
        echo "{$this->Unvan} {$this->Isim} {$this->Soyisim}<br>";
    }
}
$uye1 = new OgretimUyesi();
$uye2 = new OgretimUyesi();
$uye1->Kaydet("Doç. Dr.", "Sinan", "Sağıroğlu");
$uye2->Kaydet("Prof. Dr.", "Fahrettin", "Topak");
echo $uye1->Unvan; // Doç. Dr. çıktılar
echo $uye1->Isim; // Sinan çıktılar
echo $uye2->Unvan; // Prof. Dr. çıktılar
echo $uye2->Isim; // Fahrettin çıktılar
?>

Görüldüğü gibi sınıf özellikleri, her nesne için farklı değerler tutuyor.

Sınıfları devralmak[değiştir]

Bir sınıf, başka bir sınıfın özellik ve metotlarını devralabilir (miras almak olarak da ifade edilir). Bu durumda devralınan sınıf ebeveyn veya üst sınıf, devralan sınıf ise çocuk veya alt sınıf olarak anılır. Alt sınıf, üst sınıfı devraldığında onun özellik ve metotlarına erişebilir. Buna kalıtım denir. Devralınacak sınıfın ismi extends anahtar sözcüğünden sonra yazılır.

<?php
class A
{
}

class B extends A
{
}
?>

Yukarıda A ve B isimli sınıflar tanımlandı. B sınıfı, A sınıfını devralıyor. Diğer bir deyişle B sınıfı, A sınıfının alt sınıfıdır. Şimdi özellik ve metotları da kullanarak bu örneği genişletelim.

<?php
class A
{
    public $BirOzellik = "Bir değer";

    public function BirMetot()
    {
        echo $this->BirOzellik;
    }
}

class B extends A
{
    public function BaskaMetot()
    {
        echo $this->BirOzellik;
    }
}
$nesne = new B();
$nesne->BirMetot();
$nesne->BaskaMetot();
?>

Örnekte B sınıfı A sınıfını devralıyor. 19. satırda $nesne nesnesi yaratılırken B sınıfı kullanılıyor. Kalıtım özelliği sayesinde B sınıfının, A sınıfının özellik ve metotlarına erişebileceğini belirtmiştik. İşte 20. satırda $nesne nesnesi üzerinden A sınıfının BirMetot isimli metoduna erişiliyor. Son satırda ise B sınıfının kendi metodu olan BaskaMetot metodu çağrılıyor. BaskaMetot metodu içerisinde, $this değişkeni kullanılarak üst sınıfın BirOzellik özelliğine erişilebildiği de dikkatinizi çekmiş olmalı.

Birden fazla sınıf devralınamaz. Bir sınıf yalnızca bir tane sınıfı devralabilir.

Özellik ve metotların görünürlüğü[değiştir]

Şimdiye dek verilen örneklerde özellik ve metotlar public anahtar sözcüğüyle tanımlandı. Ancak public dışında kullanılabilecek iki anahtar sözcük daha vardır: protected ve private. Bu anahtar sözcükler, özellik ve metotların görünürlüğünü veya başka bir deyişle erişilebilirliğini ifade eder.

  • public tanımlı özellik ve metotlara sınıf içerisinden, alt sınıflardan ve nesneler üzerinden erişilebilir.
  • protected tanımlı özellik ve metotlara sınıf içerisinden ve alt sınıflardan erişilebilir. Nesneler üzerinen erişilemez.
  • private tanımlı özellik ve metotlara sınıf içerisinden erişilebilir. Alt sınıflardan ve nesneler üzerinden erişilemez.

Örnek üzerinde görelim:

<?php
class BirSinif
{
    public $PubOzellik = "Bu public özelliktir";
    protected $ProOzellik = "Bu protected özelliktir";
    private $PriOzellik = "Bu private özelliktir";
}
$nesne = new BirSinif();
echo $nesne->PubOzellik;
echo $nesne->ProOzellik; // erişemez
echo $nesne->PriOzellik; // erişemez
?>

Örnekte $nesne nesnesi üzerinden üç özelliğe de erişmek istedik. Ancak ProOzellik ve PriOzellik özelliklerine erişemeyiz çünkü bunlar protected ve private olarak tanımlanmıştır. $nesne üzerinden yalnızca public olarak tanımlı PubOzellik özelliğine erişilebilir.

Bir de metotları kullanalım:

<?php
class BirSinif
{
    public function PubMetot()
    {
        echo "Bir değer";
    }

    protected function ProMetot()
    {
        echo "Bir değer";
    }

    private function PriMetot()
    {
        echo "Bir değer";
    }
}
$nesne->PubMetot();
$nesne->ProMetot(); // erişemez
$nesne->PriMetot(); // erişemez
?>

protected ve private tanımlı özelliklere nesne üzerinden erişmek istenirse, public tanımlı bir metot kullanılır. Aşağıdaki örneği inceleyiniz.

<?php
class BirSinif
{
    public $PubOzellik = "Bu public özelliktir";
    protected $ProOzellik = "Bu protected özelliktir";
    private $PriOzellik = "Bu private özelliktir";

    public function BirMetot()
    {
        echo $this->PubOzellik;
        echo $this->ProOzellik;
        echo $this->PriOzellik;
    }
}
$nesne = new BirSinif();
$nesne->BirMetot();
?>

Gördüğünüz gibi, public olarak tanımlanmış bir metot kullanarak tüm özelliklerin değerlerine sınıf dışından erişebildik.

Şimdi de bir alt sınıf kullanalım.

<?php
class UstSinif
{
    public $PubOzellik = "Bu public özelliktir";
    protected $ProOzellik = "Bu protected özelliktir";
    private $PriOzellik = "Bu private özelliktir";

    private function PriMetot()
    {
        echo "Bir ifade";
    }
}

class AltSinif extends UstSinif
{
    public function BirMetot()
    {
        echo $this->PubOzellik; // erişir
        echo $this->ProOzellik; // erişir
        echo $this->PriOzellik; // erişemez
        $this->PriMetot(); // erişemez
    }
}
?>

Sınıf özellikleri sabit ifadelerle ilklendirilmelidir. Yani:

<?php
class BirSinif
{
    public $sayi = 5 * 4; // hatalı
    public $ifade = "Viki" . "kitap"; // hatalı
    public $ozellik = $degisken; // hatalı
    public $ifade = "Vikikitap"; // geçerli
    public $sayi = 20; // geçerli
    public $dizi = array("a", "b"); // geçerli
}
?>

Sınıf sabitleri[değiştir]

Sınıfların içinde sabit tanımları yapılabilir.

<?php
class BirSinif
{
    const BirSabit = "Bir değer";
}
echo BirSinif::BirSabit; // "Bir değer" çıktılar
?>

Sınıf sabitlerine erişmek için nesne yaratmaya gerek yoktur. Sınıf sabitlerine :: operatörü kullanılarak erişilir. Operatörden önce sınıfın ismi, sonra da erişilecek sabitin ismi yazılır. İlgili olarak bkz: Sabitler

Sınıf sabitlerine, sınıf içerisinden nasıl erişileceğine sayfanın ileri kısımlarında self anahtar sözcüğünün açıklandığı başlıkta değinilmiştir.

Statik özellik ve metotlar[değiştir]

Statik olarak tanımlanmış özellik ve metotlara, sınıf dışından nesne yaratmadan erişilebilir. Statik özellik ve metotlar static anahtar sözcüğüyle tanımlanır.

<?php
class BirSinif
{
    public static $BirOzellik = "Bir değer";

    public static function BirMetot()
    {
        echo "Bir ifade";
    }
}
echo BirSinif::$BirOzellik;
BirSinif::BirMetot();
?>

Sınıf sabitlerinde olduğu gibi static olarak tanımlanmış özellik ve metotlara erişirken de :: operatörü kullanılıyor. static olarak tanımlı özellik ve metotlara erişmek için nesne yaratmaya gerek yoktur. Zaten nesneler üzerinden, statik özelliklere erişilemez. Ama statik metotlara erişilebilir.

Statik olmayan özelliklerin, her nesne için farklı değerler tuttuğunu biliyoruz. Ancak statik özellikler adı üstünde statik olduğundan ve nesneler ile erişilemediğinden doğal olarak son aldıkları değeri -yani tek bir değer- tutarlar.

Statik özelliklere, sınıf içerisinden nasıl erişileceğine sayfanın ileri kısımlarında self anahtar sözcüğünün açıklandığı başlıkta değinilmiştir.

Kurucular[değiştir]

Sınıf kurucuları, her nesne yaratılışında çalışır ve kendiliğinden birtakım işleri yerine getirir. Kurucu metot, __construct ismiyle tanımlanır. Kurucu metot, public olmalıdır. Aksi durumda kurucuya erişilemeyeceğinden kurucu çalışamayacaktır.

<?php
class BirSinif
{
    public function __construct()
    {
        echo "Nesne yaratıldı";
    }
}
$nesne = new BirSinif();
?>

Örnekte $nesne nesnesi yaratıldığı anda kurucu metot çalışacak ve işlevini yerine getirecektir.

Başka bir örnek:

<?php
class OgretimUyesi
{
    private $Unvan;
    private $Isim;
    private $Soyisim;

    public function __construct($unvan, $isim, $soyisim)
    {
        $this->Unvan = $unvan;
        $this->Isim = $isim;
        $this->Soyisim = $soyisim;
    }

    public function Getir()
    {
        echo "{$this->Unvan} {$this->Isim} {$this->Soyisim}";
    }
}
$uye = new OgretimUyesi("Prof. Dr.", "Fahrettin", "Topak");
$uye->Getir();
?>

Bu örnekteki kurucu metot, üç adet parametre alıyor ve parametre olarak aldığı değerleri, sınıfın özelliklerine atıyor. Getir metodu da bu özelliklere erişmemizi sağlıyor. Kurucu metodun parametrelerinin alacağı değerlerin, nesne yaratılırken gönderildiğine dikkat ediniz.

PHP birden fazla kurucu tanımlanmasını desteklemez.

Alt sınıftan üst sınıfın kurucusuna nasıl erişileceğine, parent anahtar sözcüğünün açıklandığı başlıkta değinilmiştir.

Yıkıcılar[değiştir]

Yıkıcı metot, nesnenin görevi bittikten sonra çalıştırılır ve kendiliğinden birtakım işler yapar. Yıkıcı metot, __destruct ismiyle tanımlanır.

<?php
class BirSinif
{
    public function __construct()
    {
        echo "Kurucu çalıştı";
    }

    public function BirMetot()
    {
        echo "BirMetot çalıştı";
    }

    public function __destruct()
    {
        echo "Yıkıcı çalıştı";
    }
}
$nesne = new BirSinif();
$nesne->BirMetot();
?>

Burada $nesne nesnesi yaratıldığı anda kurucu metot çalışacaktır. Alt satırda çağrılan BirMetot metodu da görevini yerine getirdikten sonra nesnenin görevi bitti için yıkıcı metot devreye girecektir.

self[değiştir]

Sınıf içerisinde sabitlere, statik özellik ve metotlara erişmeyi sağlar.

<?php
class BirSinif
{
    public static $BirOzellik = "Bir değer";
    const BirSabit = "Bir değer";

    public static function BirMetot()
    {
        echo "Bir metot";
    }
	
    public function BaskaMetot()
    {
        echo self::$BirOzellik;
        echo self::BirSabit;
        self::BirMetot();
    }
}
?>

Görüldüğü gibi self anahtar sözcüğü kullanılarak BaskaMetot isimli metotta sabite, statik özelliğe ve statik metoda erişildi.

parent[değiştir]

Üst sınıfın sabitlerine, statik özellik ve metotlarına erişmeyi sağlar.

<?php
class UstSinif
{
	public static $BirOzellik = "Bir değer";
	const BirSabit = "Bir değer";
	
	public static function BirMetot()
	{
		echo "Bir metot";
	}
}

class AltSinif extends UstSinif
{
	public function __construct()
	{
		echo parent::$BirOzellik;
		echo parent::BirSabit;
		parent::BirMetot();
	}
}
?>

Örnekte, alt sınıfın kurucusundan parent anahtar sözcüğü ve :: operatörü kullanılarak üst sınıfın sabitine ve statik özelliğiyle metoduna erişildi.

parent kullanarak üst sınıfın kurucusunu çağırma örneği:

<?php
class UstSinif
{
    public function __construct()
    {
        echo "Üst sınıf kurucusu çağrıldı.";
    }
}

class AltSinif extends UstSinif
{
    public function __construct()
    {
        echo "Alt sınıf kurucusu çalıştı";
        parent::__construct();
    }
}
?>

final[değiştir]

Üst sınıfta final olarak tanımlanmış bir metot, alt sınıfta yeniden tanımlanamaz (override). Örneğin:

<?php
class UstSinif
{
    public final function Metot()
    {
        echo "Bir şey";
    }
}

class AltSinif extends UstSinif
{
    public function Metot() // hatalı. Metot final olarak tanımlı
    {
        echo "Başka bir şey";
    }
}
?>

Sınıflar da final olarak tanımlanabilir. final olarak tanımlı sınıflar devralınamaz.

<?php
final class UstSinif
{
}

class AltSinif extends UstSinif // hatalı. UstSinif final olarak tanımlı
{
}
?>