Php Kalıtım (inheritance)

php-oop Php sınıf yapılarından bahsettiğim şu yazımda kalıtım konusunu kısaca anlatmış ve bir örnek vermiştim. Bu yazıda kalıtımın detaylarına inmek, avantajlarından bahsetmek ve ek birkaç örnek daha göstermek istiyorum.

Kalıtım bizi kod tekrarından ve aynı işi yapan metotları farklı sınıflarda tanımlamaktan kurtarır. Daha önce örnek verdiğimiz araba ve motosiklet sınıfları üzerinden anlatalım. Her arabanın bir rengi ve tekerlekleri bulunur. Aynı durum motosiklet için de geçerlidir. Eğer kalıtımdan faydalanmazsak her sınıfta renk ve tekerlek için ayrı, ayrı metotlar tanımlamamız gerekir. Aynı durum öğrenci ve öğretmen sınıfları için de geçerlidir. Her ikisinin de kendilerine has özellikleri bulunduğu gibi, ad, soyad, yaş gibi ortak özellikleri de bulunmaktadır. Önceki yazımdan alıntı yaparak örneğimize geçmek istiyorum.

Kalıtım, bir sınıfın özellik ve metotlarını başka bir sınıfa aktarmasını ve aktarılan elemanların alt sınıf tarafından kullanılmasını sağlar. Herhangi bir sınıf başka bir sınıfın elemanlarını miras alırken extends deyimini kullanır. Bu durumda elemanlarını devreden sınıf üst sınıf, üst sınıfın elemanlarını devralan sınıf da alt sınıf olarak adlandırılır.
Araba sınıfımıza ek olarak bir de Motosiklet sınıfı oluşturalım. Motosiklet sınıfımız Araba sınıfının alt sınıfı olsun. Motosiklet sınıfımız için nesnemizi oluşturalım ve Araba sınıfına ait elemanları kullanalım.

<?php
class Araba {
 
 // sınıf özelliğini tanımlıyoruz
 public $renk;
 
 
 // $renk özelliğini getiren metot
 public function getRenk() {
 return $this->renk;
 }
 
}
 
/*
Motosiklet sınıfımız araba sınıfının elemanlarını miras alıyor
*/
class Motosiklet extends Araba {
 
 // sınıf özelliğini tanımlıyoruz
 public $tekerlek;
 
 // $tekerlek özelliği getiren metot
 public function getTekerlek() {
 return $this->tekerlek;
 }
 
}
 
$motor = new Motosiklet(); // nesnemizi oluşturuyoruz
$motor->renk = 'Siyah'; // Araba sınıfının özelliğine erişiyoruz
$motor->tekerlek = 2;
echo $motor->getRenk() . '<br />'; // Araba sınıfına ait metodumuzu çağırıyoruz
echo $motor->getTekerlek(); // metodumuzu çağırıyoruz
?>

Oluşturduğumuz alt sınıfımızdan, üst sınıfımıza ait özellik ve metotları kullanabiliyoruz.

Overriding (Geçersiz Kılma)

Bazı durumlarda üst sınıftan miras alınan özellik ve metotları yeniden tanımlamak, özelliklere farklı değerler atamak veya metotların işlevlerini değiştirmeye ihtiyaç duyarız. Bu işlem overriding (geçersiz kılma) olarak adlandırılır.

<?php
class Araba {
 
 // sınıf özelliğini tanımlıyoruz
 public $renk = 'Mavi';
 
 
 // $renk özelliğini getiren metot
 public function getRenk() {
 return $this->renk;
 }
 
}
 
/*
Motosiklet sınıfımız araba sınıfının elemanlarını miras alıyor
*/
class Motosiklet extends Araba {
 
 // sınıf özelliğini tanımlıyoruz
 // üst sınıftan miras alınan özellik devre dışı bırakılıyor.
 public $renk = 'Kırmızı';
 
}
 
$motor = new Motosiklet(); // nesnemizi oluşturuyoruz
echo $motor->getRenk(); // Araba sınıfına ait metodumuzu çağırıyoruz
// Çıktı: Kırmızı
?>

Bir örnek de metot overriding üzerine yapalım.

<?php
class Araba {

 public function getRenk() {
 return 'Mavi';
 }
 
}
 
/*
Motosiklet sınıfımız araba sınıfının elemanlarını miras alıyor
*/
class Motosiklet extends Araba {
 
 // $renk özelliğini getiren metot
 // üst sınıftan miras alınan metot devre dışı bırakılıyor.
 public function getRenk() {
 return 'Kırmızı';
 }
 
}
 
$motor = new Motosiklet(); // nesnemizi oluşturuyoruz
echo $motor->getRenk(); // Metodumuzu çağırıyoruz
// Çıktı: Kırmızı
?>

Miras aldığımız özellik ve metotları alt sınıfta değiştirebiliyoruz ve alt sınıftan çağırdığımız özellik ve metotlar yeniden tanımlandığı haliyle çalışıyorlar.

Geçersiz kılmak, üst sınıftaki özellik ve metotları etkilemez. Ayrıca, overriding yapılmadığı sürece devralınan metot ve özellikler üst sınıfta tanımlandığı şeklini korur ve aynı şekilde çalışırlar.

<?php
class Araba {

 public function getRenk() {
 return 'Mavi';
 }
 
}
 
/*
Motosiklet sınıfımız araba sınıfının elemanlarını miras alıyor
*/
class Motosiklet extends Araba {
 
 // $renk özelliğini getiren metot
 // üst sınıftan miras alınan metot devre dışı bırakılıyor.
 public function getRenk() {
 return 'Kırmızı';
 }
 
}
 
$motor = new Motosiklet(); // nesnemizi oluşturuyoruz
echo $motor->getRenk(); // Metodumuzu çağırıyoruz
// Çıktı: Kırmızı
echo '<br />';
$araba = new Araba(); // nesnemizi oluşturuyoruz
echo $araba->getRenk(); // Metodumuzu çağırıyoruz
// Çıktı: Mavi
?>

Araba sınıfının metodu, alt sınıfta geçersiz kılındığı halde üst sınıfta tanımlı halini değiştirmedi.
Bir metot devre dışı bırakılırken, üst sınıfta tanımlı metotla aynı sayıda parametre almalıdır. Aksi halde “Strict Standards” uyarısı alırsınız.

Üst Sınıf Metotlarına Erişme (Parent)

Üst sınıfta tanımlı metotlara erişmek için parent anahtar sözcüğü iki nokta (::) ile beraber kullanılır. Üst sınıfta tanımlı metodu geçersiz kılsak dahi, parent:: anahtar sözcüğüyle metodun üst sınıfta tanımlı haline erişiriz.

<?php
class Araba {

public function getRenk() {
 echo 'Mavi';
}

}
 
/*
Motosiklet sınıfımız araba sınıfının elemanlarını miras alıyor
*/
class Motosiklet extends Araba {

// Motosiklet sınıfına ait getRenk() metodunu tanımlıyoruz.
 public function getRenk() {
 parent::getRenk(); // Üst sınıfa (Araba) ait getRenk metodu çağrılıyor.
 echo '<br />';
 echo 'Kırmızı';
 }
 
}
 
$motor = new Motosiklet(); // nesnemizi oluşturuyoruz
$motor->getRenk(); // Metodumuzu çağırıyoruz

/*
Çıktı:
Mavi
Kırmızı
*/
?>

Alt sınıfımızdan (Motosiklet), üst sınıfımızda (Araba) tanımlı getRenk() metodunu çağırdık ve üst sınıfta tanımlandığı gibi çalışıp “Mavi” çıktısını verdi.

Parent anahtar sözcüğü üst sınıfa ait yapılandırıcıyı çağırırken de kullanılır.

<?php
class Araba {

 function __construct() {
 echo 'Araba sınıfının yapılandırıcısı <br />';
 }

}
 
/*
Motosiklet sınıfımız araba sınıfının elemanlarını miras alıyor
*/
class Motosiklet extends Araba {

 function __construct() {
 parent::__construct();
 echo 'Motosiklet sınıfının yapılandırıcısı';
 }
 
}
 
$motor = new Motosiklet(); // nesnemizi oluşturuyoruz

/*
Çıktı:
Araba sınıfının yapılandırıcısı 
Motosiklet sınıfının yapılandırıcısı
*/
?>

Kalıtımı ve Geçersiz Kılmayı Önlemek (final)

Sınıf içerisinde yazdığımız bazı metotların alt sınıflar tarafından değiştirilmesini yani geçersiz kılınmasını istemeyebiliriz. Ya da bir sınıfın alt sınıfının oluşturulmaması gerekebilir. Bu durumlarda final anahtar sözcüğü kullanılır.

<?php
class Araba {

 final function getRenk() {
 return 'Mavi';
 }
 
}
 
/*
Motosiklet sınıfımız araba sınıfının elemanlarını miras alıyor
*/
class Motosiklet extends Araba {
 
/*
getRenk metodu final olarak tanımlandığı için
geçersiz kılınamaz
*/
 public function getRenk() {
 return 'Kırmızı';
 }
 
}
 
$motor = new Motosiklet(); // nesnemizi oluşturuyoruz
echo $motor->getRenk(); // Metodumuzu çağırıyoruz
?>

Sayfayı çağırdığınız zaman “Fatal error: Cannot override final method Araba::getRenk() …” hatası alırsınız. Aynı kullanım şekli sınıflar için de geçerlidir.

<?php

// araba sınıfımızı final olarak tanımlıyoruz
final class Araba {

 final function getRenk() {
 return 'Mavi';
 }
 
}
 
/*
final olarak tanımlandığı için Araba sınıfı miras alınamaz
*/
class Motosiklet extends Araba {
 
}
 
$motor = new Motosiklet(); // nesnemizi oluşturuyoruz

?>

Aynı şekilde “Fatal error: Class Motosiklet may not inherit from final class (Araba) …” hatası alıyoruz.

Yazı biraz uzun olduğu için önemli bazı noktaları maddeler halinde listelemek istiyorum.

  • Kalıtım: bir sınıfın özellik ve metotlarını başka bir sınıfa aktarmasını ve aktarılan elemanların alt sınıf tarafından kullanılmasını sağlar.
  • Kalıtım bizi kod tekrarından ve aynı işi yapan metotları farklı sınıflarda tanımlamaktan kurtarır.
  • Herhangi bir sınıf başka bir sınıfın elemanlarını miras alırken extends deyimini kullanır.
  • Üst sınıftan miras alınan elemanları, alt sınıfta yeniden tanımlamak, overriding (geçersiz kılma) olarak adlandırılır.
  • Geçersiz kılmak, üst sınıftaki özellik ve metotları etkilemez.
  • Overriding yapılmadığı sürece devralınan metot ve özellikler üst sınıfta tanımlandığı şeklini korur ve aynı şekilde çalışırlar.
  • Bir metot devre dışı bırakılırken, üst sınıfta tanımlı metotla aynı sayıda parametre almalıdır. Aksi halde “Strict Standards” uyarısı alırsınız.
  • Üst sınıfta tanımlı metotlara erişmek için parent:: anahtar sözcüğü, iki nokta (::) ile beraber kullanılır.
  • Parent anahtar sözcüğü üst sınıfa ait yapılandırıcıyı çağırırken de kullanılır.
  • Final anahtar sözcüğü, bir sınıfın, alt sınıflarının oluşturulmasını ve bir metodun geçersiz kılınmasını engeller.

Henüz Yorum Yapan Olmadı

Yorum Yapın