Nesne Arayüzleri
Nesne arayüzleri, bir sınıfın gerçeklemesi gereken yöntemlerin
belirtildiği kodu, bu yöntemlerin nasıl gerçekleneceğini tanımlamaksızın
oluşturmanıza imkan sağlar. Arayüzler, sınıflar ve niteliklerle aynı isim
alanını paylaşır, bu nedenle aynı adı kullanmayabilirler.
Arayüzler, sınıflardan farklı olarak class
yerine
interface
anahtar sözcüğü kullanılarak ve içeriğinde
hiçbir tanımlı yöntem olmaksızın tanımlanırlar.
Bir arayüzdeki tüm yöntemler, arayüzün doğası gereği public
olarak bildirilmelidir.
Uygulamada, arayüzler birbirlerini tamamlayan iki amaca hizmet eder::
-
Geliştiricilerin, aynı arayüzü veya arayüzleri gerçekledikleri için
birbirlerinin yerine kullanılabilecek farklı sınıflardan nesneler
oluşturabilmelerini sağlamak. Böylece, kullanıldıkları kodda herhangi bir
değişiklik yapılmasına gerek kalmadan bu farklı gerçeklenimler arasında
geçiş yapılabilir. Yaygın bir örnek, çoklu veritabanı erişim hizmetleri,
çoklu ödeme ağ geçitleri veya farklı önbelleğe alma stratejileridir.
-
Nesnenin başka ne yapabileceğini veya nasıl uygulandığını umursamadan,
bir işlev veya yöntemin arayüze uyan bir değiştirgeyi kabul etmesini ve
üzerinde çalışmasını sağlamak. Bu arayüzler, davranışın önemini açıklamak
için genellikle
Iterable
(Yinelenebilir),
Cacheable
(Önbelleğe Alınabilir),
Renderable
(Yorumlanabilir) vb. şeklinde adlandırılır.
Arayüzler, bu yöntemleri gerçeklemek için sınıfların gerçeklenmesini
gerektiren sihirli yöntemler
tanımlayabilir.
Bilginize:
Destekleniyor olsa bile, arayüzlere kurucuların dahil
edilmesi kesinlikle önerilmez. Bunu yapmak, arayüzü gerçekleyen nesnenin
esnekliğini önemli ölçüde azaltır. Ek olarak, kurucular, tutarsız ve
beklenmeyen davranışlara neden olabilecek miras alma kuralları tarafından
zorlanmaz.
implements
işleci
Bir arayüzü gerçeklemek için, implements
işleci
kullanılır. Arayüzdeki tüm yöntemler bir sınıf içersinde
gerçeklenmelidir; aksi takdirde bir ölümcül hata alırsınız. Bir sınıfın,
aralarına virgül koyarak birden fazla arayüzü gerçeklemesi sağlanabilir.
Uyarı
Bir sınıf, yöntem bildirimleri aynı olan aynı isimli iki arayüzü
gerçekleyebilir.
Uyarı
Bir arayüzü gerçekleyen bir sınıf, değiştirgeleri için arayüzdekinden
farklı bir ad kullanabilir. Bununla birlikte, PHP 8.0'dan itibaren dil,
isimli değiştirgeleri
desteklemektedir, bu da çağrıcıların arayüzdeki
değiştirge adına güvenebileceği anlamına gelir. Bu nedenle,
geliştiricilerin gerçeklenen arayüzle aynı değiştirge adlarını
kullanmaları şiddetle tavsiye edilir.
Bilginize:
Arayüzler, sınıflar gibi
extends işleciyle genişletilebilir.
Bilginize:
Bir sınıf bir arayüzü gerçeklerken, bunu
değiştirge adı ve sırası arayüzle
uyumlu yöntemler kullanarak yapmalıdır.
Sabitler
Arayüzlerin sabitlerinin olması mümkündür. Arayüz sabitleri, kendilerini
miras alan sınıflar veya arayüzler tarafından geçersiz kılınamamaları
dışında tıpkı sınıf sabitleri
gibi çalışır.
Örnekler
Örnek 1 - Arayüz örneği
<?php
// 'iTemplate' arayüzünü tanımlayalım
interface iTemplate
{
public function setVariable($name, $var);
public function getHtml($template);
}
// Arayüzü gerçekleyelim
// Bu çalışacaktır
class WorkingTemplate implements Template
{
private $vars = [];
public function setVariable($name, $var)
{
$this->vars[$name] = $var;
}
public function getHtml($template)
{
foreach($this->vars as $name => $value) {
$template = str_replace('{' . $name . '}', $value, $template);
}
return $template;
}
}
// Bu çalışmayacaktır
// Ölümcül hata: BadTemplate sınıfı 1 soyut yöntem içermektedir
// dolayısıyla soyut olarak tanımlanması gerekir (Template::getHtml)
class BadTemplate implements Template
{
private $vars = [];
public function setVariable($name, $var)
{
$this->vars[$name] = $var;
}
}
?>
Örnek 2 - Genişletilebilir Arayüzler
<?php
interface A
{
public function foo();
}
interface B extends A
{
public function baz(Baz $baz);
}
// Bu çalışır
class C implements B
{
public function foo()
{
}
public function baz(Baz $baz)
{
}
}
// Bu çalışmaz, ölümcül hatayla sonuçlanır
class D implements B
{
public function foo()
{
}
public function baz(Foo $foo)
{
}
}
?>
Örnek 3 - Çok sayıda arayüz oluşturma
<?php
interface A
{
public function foo();
}
interface B
{
public function bar();
}
interface C extends A, B
{
public function baz();
}
class D implements C
{
public function foo()
{
}
public function bar()
{
}
public function baz()
{
}
}
?>
Örnek 4 - Arayüzler ve sabitleri
<?php
interface A
{
const B = 'Arayüz sabiti';
}
// Şunu basar: Arayüz sabiti
echo A::B;
// Sabitler geçersiz kılınamayacağından bu çalışmaz.
class B implements A
{
const B = 'Sınıf sabiti';
}
?>
Örnek 5 - Soyut sınıflı arayüzler
<?php
interface A
{
public function foo(string $s): string;
public function bar(int $i): int;
}
// Bir soyut sınıf bir arayüzün sadece bir bölümünü gerçekleyebilir.
// Kalanını soyut sınıfı genişleten sınıflar gerçeklemelidir.
abstract class B implements A
{
public function foo(string $s): string
{
return $s . PHP_EOL;
}
}
class C extends B
{
public function bar(int $i): int
{
return $i * 2;
}
}
?>
Örnek 6 - Aynı anda genişletme ve gerçekleme
<?php
class One
{
/* ... */
}
interface Usable
{
/* ... */
}
interface Updatable
{
/* ... */
}
// Burada sözcük sırası önemli: 'extends' önce gelmeli.
class Two extends One implements Usable, Updatable
{
/* ... */
}
?>
Bir arayüz tür bildirimiyle belli bir nesnenin belli yöntemleri içermesini
sağlayabilir. Ayrıca bakınız:
instanceof işleci ve
Tür Bildirimleri.