PHP 7.2.0'da, bir çocuk yöntem bağımsız değişkenlerindeki tür sınırlamaları kaldırılarak az özgüllüklere kısmen girildi. PHP 7.4.0'dan itibaren, az ve çok özgüllüklere tam destek eklendi.
Çok özgüllük, bir çocuk yöntemin ebeveyn yönteminden daha özellikli bir tür döndürmesine izin verir. Buna karşın, az özgüllük, bir bağımsız değişkenin bir çocuk yöntemin içinde ebeveyndekinden daha az özellikli olmasına izin verir.
Aşağıdaki durumda tür belirtiminin daha belirgin olduğu varsayılır:
Çok özgüllüğün nasıl çalıştığını göstermek için, basit bir soyut ebeveyn sınıf olarak Hayvan sınıfı oluşturulup Kedi ve Köpek çocuk sınıflarına genişletildi.
<?php
abstract class Hayvan
{
protected string $isim;
public function __construct(string $isim)
{
$this->name = $isim;
}
abstract public function konuş();
}
class Köpek extends Hayvan
{
public function konuş()
{
echo $this->name . " havlar";
}
}
class Kedi extends Hayvan
{
public function konuş()
{
echo $this->name . " miyavlar";
}
}
Bu örnekte yöntemlerin hiçbiri değer döndürmemektedir. Hayvan, Kedi ve Köpek sınıfı türünde yeni bir nesne döndüren birkaç arayüz eklenecektir.
<?php
interface HayvanYuvası
{
public function sahiplen(string $isim): Hayvan;
}
class KediYuvası implements HayvanYuvası
{
public function sahiplen(string $isim): Kedi // Hayvan türünde bir sınıf yerine Kedi türünde bir sınıf döner
{
return new Kedi($isim);
}
}
class KöpekYuvası implements HayvanYuvası
{
public function sahiplen(string $isim): Köpek // Hayvan türünde bir sınıf yerine Köpek türünde bir sınıf döner
{
return new Köpek($isim);
}
}
$mırnav = (new KediYuvası)->sahiplen("Tekir");
$mırnav->konuş();
echo "\n";
$kuçu = (new KöpekYuvası)->sahiplen("Çomar");
$kuçu->konuş();
Yukarıdaki örneğin çıktısı:
Tekir miyavlar Çomar havlar
Hayvan, Kedi ve Köpek sınıflarıyla önceki örneğe devam ederek, bunlara Yem ve HayvanYemi sınıflarını dahil edip Hayvan soyut sınıfına ye(HayvanYemi $yem) yöntemini ekleyelim.
<?php
class Yem {}
class HayvanYemi extends Yem {}
abstract class Hayvan
{
protected string $isim;
public function __construct(string $isim)
{
$this->name = $isim;
}
public function ye(HayvanYemi $yem)
{
echo $this->name . " " . get_class($yem) . "yer";
}
}
Az özgüllüğün davranışını görmek için, herhangi bir Yem türü nesneye izin vermek için Köpek sınıfında ye yöntemi geçersiz kılınır. Kedi sınıfı değişmeden kalır.
<?php
class Köpek extends Hayvan
{
public function ye(Yem $yem) {
echo $this->name . " " . get_class($yem) . "yer";
}
}
Aşağıdaki örnek az özgüllüğün davranışını gösterir:
<?php
$mırnav = (new KediYuvası)->sahiplen("Tekir");
$kediYemi = new HayvanYemi();
$mırnav->ye($kediYemi);
echo "\n";
$kuçu = (new KöpekYuvası)->sahiplen("Çomar");
$kemik = new Yem();
$kuçu->ye($kemik);
Yukarıdaki örneğin çıktısı:
Tekir HayvanYemi yer Çomar Yem yer
Peki $mırnav $kemik ye()meye çalışırsa ne olur?
$mırnav->ye($kemik);
Yukarıdaki örneğin çıktısı:
Fatal error: Uncaught TypeError: Argument 1 passed to Hayvan::ye() must be an instance of HayvanYemi, instance of Yem given Türkçesi: Ölümcül hata: ... : Hayvan::ye() yöntemine aktarılan 1. bağımsız değişken bir HayvanYemi örneği olmalı, Yem örneği verildi