Burhan T. 5 dakikalık okuma
June 18, 2017

PHP’de Abstract Class’lara detaylı bakış

  1. Abstract Class nedir?
  2. Abstract Class’a neden ihtiyaç duyarız ve PHP diline neden girmiştir ?
  3. Abstract Class nasıl oluşturulur ve kullanılır ?

Şimdi bu 3N sorularımızı cevaplayalım:

 1. ABSTRACT CLASS NEDİR?

Abstract sınıflar, içerisinde normal yani içi dolu metodların,değişkenlerin ve interface’lerdeki gibi sadece metod isimlerinin tanımlandığı yapılardır.

Interface ile kullanım konsepti hemen hemen aynıdır; bazı fark ve esnekliklerle ayrılır.

Ayrıca bir sınıfın abstract metod bulundurabilmesi için Abstract bir sınıf olması gerekir.

abstract class Arabalar {

abstract public function BMW();

}

2. ABSTRACT CLASS’A NEDEN İHTİYAÇ DUYARIZ VE PHP DİLİNE NEDEN GİRMİŞTİR ?

Aslında bunu adam akıllı nasıl anlatsam diye uzun uzun düşündüm. Çünkü anlattığım bir şeyi somuta dökemediğim takdirde karşıdaki kişi neden ihtiyaç var ki diye konuyu tam anlamıyor ya da o konunun önemsiz olduğunu düşünüyor.

Neyse, böyle bir düşünce içerisindeyken internette karşıma yazılım mühendisi Cihat Altuntaş’ın abstract’larla ilgili nefis örneği çıktı. Bu örnekle bu mesele bundan daha iyi anlatılamazdı.

Örnek şöyle:

Arabalarla alakalı geliştirdiğimiz bir uygulamamız olsun. Sistemimizde bulunan çeşitli marka arabalara ait bazı özellikleri ekranda göstersin. Arabaların ağırlık,renk,model gibi ortak özellikleri ve cant kalınlığı,devir sayısı gibi kendilerine has özellikleri mevcut. Bunu ifade eden aşağıdaki gibi kodumuzu yazalım.

class Araba{
    private $agirlik;
    private $renk;
    private $model;

    public function getAgirlik() {
        return $this->agirlik;
    }
    public function setAgirlik($yeniagirlik) {
        $this->agirlik = $yeniagirlik;
    }
    public function getRenk() {
        return $this->renk;
    }
    public function setRenk($yenirenk) {
        $this->renk = $yenirenk;
    }
    public function getModel() {
        return $this->model;
    }
    public function setModel($yenimodel) {
        $this->model = $yenimodel;
    }


}

class Mercedes extends Araba{
    private $cantKalinligi;

    public function getCantKalinligi() {
        return $this->cantKalinligi;
    }
    public function setCantKalinligi($yenicantKalinligi) {
        $this->cantKalinligi = $yenicantKalinligi;
    }



}

class Ford extends Araba{
    private $devirSayisi;

    public function getDevirSayisi() {
        return $this->devirSayisi;
    }
    public function setDevirSayisi($yenidevirSayisi) {
        $this->devirSayisi = $yenidevirSayisi;
    }



}

Yukarıdaki kodda gördüğünüz gibi bir sınıf oluşturduk; fakat burada şöyle bir problem var her marka arabanın kaç litre benzin yaktığı kendi ağırlığına göre farklı hesaplanıyor.Araba sınıfına saatte yaktığı litre diye değişken eklesek olmayacak çünkü Mercedes bunu hesaplamak için farklı katsayı ile çarpıyor Ford farklı sayı ile çarpıyor.İşte bu noktada yardımımıza Abstract kavramı yetişiyor ve kodumuzu şöyle değiştiriyoruz:

Abstract class Araba{
    private $agirlik;
    private $renk;
    private $model;
    private $cantKalinligi;
    private $devirSayisi;

    public function getAgirlik() {
        return $this->agirlik;
    }
    public function setAgirlik($yeniagirlik) {
        $this->agirlik = $yeniagirlik;
    }
    public function getRenk() {
        return $this->renk;
    }
    public function setRenk($yenirenk) {
        $this->renk = $yenirenk;
    }
    public function getModel() {
        return $this->model;
    }
    public function setModel($yenimodel) {
        $this->model = $yenimodel;
    }

    public function getCantKalinligi() {
        return $this->cantKalinligi;
    }
    public function setCantKalinligi($yenicantKalinligi) {
        $this->cantKalinligi = $yenicantKalinligi;
    }



    public function getDevirSayisi() {
        return $this->devirSayisi;
    }
    public function setDevirSayisi($yenidevirSayisi) {
        $this->devirSayisi = $yenidevirSayisi;
    }


    //Bu metod abstact olarak çocuk sınıflar içerisinde içerisi kodlanacak... Çünkü her arabanın yakıt benzini litresi hazırlama katsayıları farklı...
    public abstract function saatteYaktigiBenzinLitresi();
}

class Mercedes extends Araba{

//----- sadece mercedes'te elektrikle şarj edilebilme özelliği  var. Tüm arabalarda bu özellik olmadığı için yukarıdaki abstract sınıf içerisine dahil etmedik.  O yüzden spesifik olarak Arabadan türeyen bu mercedes çocuk sınıfında ek olarak bu özellikleri de ekliyoruz.
    private $sarjsuresi;

    public function getSarjSuresi() {
        return $this-> sarjsuresi;
    }
    public function setSarjSuresi($yenisure) {
        $this->sarjsuresi = $yenisure;
    }


    //Bu hesaplamayı gördüğünüz gibi her marka araba sınıfı kendi katsayılarına göre kendi içinde yapıyor.
    //Bu yüzden abstract sınıfta abstract metod olarak işaretlemiştik. Burada da içini dolduruyoruz.
    public function saatteYaktigiBenzinLitresi() {
        return getAgirlik()*1;
    }
}

class Ford extends Araba{


    //Bu hesaplamayı gördüğünüz gibi her marka araba sınıfı kendi katsayılarına göre kendi içinde yapıyor.
    //Bu yüzden abstract sınıfta abstract metod olarak işaretlemiştik. Burada da içini dolduruyoruz.
    public function saatteYaktigiBenzinLitresi() {
        return getAgirlik()*1;
    }

}

3. ABSTRACT CLASS NASIL OLUŞTURULUR VE KULLANILIR ?

A. abstract anahtar kelimesiyle sınıf tanımlarız:

abstract class Arabalar {

abstract public function BMW();

}

B. Abstract sınıfımızın içerisinde abstract olmayan metodlar kullanabilir miyiz ?

Cevap: Evet. Kullanabiliriz. İşte bu özelliği ile Interface’den ayrılır ve Abstractlara esneklik katar.

Örnek:

abstract class Arabalar {

// Abstract sınıflar properties(özelliklere) sahip olabilirler.

protected $adet;

// Abstract sınıflar abstract olmayan metodlara sahip olabilirler.

public function adetBelirle($nekadar)

{

$this -> adet = $nekadar;
}

// Bu da abstract metod

abstract public function Cam();

}

C. Abstract sınıflar create edilemezler:

abstract class Arabalar {

abstract public function Cam();

}

$araba = new Arabalar // Bu kod çalışmayacak. Hata verecek. Çünkü abstract sınıflar create edilemez. Bu yüzden direkt kullanılamazlar. Bir sınıftan implement edilerek kullanılmaları gerekir.

D. Abstract sınıftan nasıl bir çocuk sınıf oluştururuz ?

Cevap:

Interface’lerde implement kullanıyorduk ya, bu iş abstractlarda extends ile yapılacak. Extend, kelime manası: genişletmek demek.

yukarıdaki örneklerde tanımladığımız Abstract Arabalar sınıfından bir çocuk sınıf oluşturalım.

class Honda extends Arabalar {

// Abstract sınıf içerisinde sadece metod ismini yazıp oluşturduğumuz ve abstract ile mühürlediğimiz 
// metodumuzun içini bu çocuk sınıf içerisinde doldurmak zorundayız. Eğer doldurmazsak hata verir.

public function Cam()

{

$sonuc = $this -> adet*30;
return $sonuc;
}

}

Şimdi abstract sınıfımızdan başka bir çocuk sınıf oluşturalım. Bunda da Cam değerini biraz değiştirip bir de çocuk sınıfta abstract sınıfımızda olmayan kendine özel başka bir metod yazalım:

class Toyota extends Arabalar {

// Abstract sınıf içerisinde sadece metod ismini yazıp oluşturduğumuz ve abstract ile 
// mühürlediğimiz metodumuzun içini bu çocuk sınıf içerisinde doldurmak zorundayız. Eğer doldurmazsak hata verir.

public function Cam()

{

return $this -> adet*33;
}

// Abstract sınıfımızda olmayan bir metod rahatlıkla çocuk sınıfa ekleyebiliyoruz. 
public function renk()

{

return “beyaz”;
}

}

Yukarıdaki sınıfın kullanımı:

$toyota1 = new Toyota();

$toyota1 -> adet(3);

echo $toyota1 -> Cam();//330

echo $toyota1 -> renk();//beyaz

**E. Abstract sınıfta tanımladığımız abstract metod public olmalı. Private olamaz. **

Private olursa abstract sınıftan oluşturacağımız çocuk sınıf içerisinde gözükemeyeceğinden metodun içini kodlayamayız…

Örnek:

abstract class Arabalar {

abstract private function Cam();  // private tanımlayamayız.  

}

Etiketler: