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 bağımsız değişkeni 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 arayüzü gerçekleyen bir sınıf, bağımsız değişkenleri için arayüzdekinden farklı bir ad kullanabilir. Bununla birlikte, PHP 8.0'dan itibaren dil, isimli bağımsız değişkenleri desteklemektedir, bu da çağrıcıların arayüzdeki bağımsız değişken adına güvenebileceği anlamına gelir. Bu nedenle, geliştiricilerin gerçeklenen arayüzle aynı bağımsız değişken 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 bağımsız değişken adı ve sırası arayüzle uyumlu yöntemler kullanarak yapmalıdır. Bir sınıf, aynı adlı yöntem bildiren birden çok arayüz gerçekleyebilir. Bu durumda gerçeklenim, tüm arayüzler için bağımsız değişken adı ve sırası uyumluk kurallarına uygun olmalıdır. Böylece, özgüllük uygulanabilir olur.

Sabitler

Arayüzlerin sabitlerinin olması mümkündür. Arayüz sabitleri, tıpkı sınıf sabitleri gibi çalışır. PHP 8.1.0 öncesinde, kendilerini miras alan sınıflar veya arayüzler tarafından geçersiz kılınamazlardı.

Örnekler

Örnek 1 - Arayüz örneği

<?php
// 'Template' arayüzünü tanımlayalım
interface Template
{
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 - Çoklu arayüzlerle özgüllük uyumluluğu

<?php
class Foo {}
class
Bar extends Foo {}

interface
A {
public function
myfunc(Foo $arg): Foo;
}

interface
B {
public function
myfunc(Bar $arg): Bar;
}

class
MyClass implements A, B
{
public function
myfunc(Foo $arg): Bar
{
return new
Bar();
}
}
?>

Örnek 4 - Ç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 5 - Arayüzler ve sabitleri

<?php
interface A
{
const
B = 'Arayüz sabiti';
}

// Şunu basar: Arayüz sabiti
echo A::B;


class
B implements A
{
const
B = 'Sınıf sabiti';
}

// Şunu basar: Sınıf sabiti
// PHP 8.1.0 öncesinde, sabitler geçersiz kılınamadığından bu çalışmazdı.
echo B::B;
?>

Örnek 6 - 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 7 - 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.

add a note add a note

User Contributed Notes 4 notes

up
32
thanhn2001 at gmail dot com
13 years ago
PHP prevents interface a contant to be overridden by a class/interface that DIRECTLY inherits it.  However, further inheritance allows it.  That means that interface constants are not final as mentioned in a previous comment.  Is this a bug or a feature?

<?php

interface a
{
    const
b = 'Interface constant';
}

// Prints: Interface constant
echo a::b;

class
b implements a
{
}

// This works!!!
class c extends b
{
    const
b = 'Class constant';
}

echo
c::b;
?>
up
18
vcnbianchi
2 years ago
Just as all interface methods are public, all interface methods are abstract as well.
up
7
williebegoode at att dot net
10 years ago
In their book on Design Patterns, Erich Gamma and his associates (AKA: "The Gang of Four") use the term "interface" and "abstract class" interchangeably. In working with PHP and design patterns, the interface, while clearly a "contract" of what to include in an implementation is also a helpful guide for both re-use and making changes. As long as the implemented changes follow the interface (whether it is an interface or abstract class with abstract methods), large complex programs can be safely updated without having to re-code an entire program or module.

In PHP coding with object interfaces (as a keyword) and "interfaces" in the more general context of use that includes both object interfaces and abstract classes, the purpose of "loose binding" (loosely bound objects) for ease of change and re-use is a helpful way to think about both uses of the  term "interface." The focus shifts from "contractual" to "loose binding" for the purpose of cooperative development and re-use.
up
1
xedin dot unknown at gmail dot com
3 years ago
This page says that if extending multiple interfaces with the same methods, the signature must be compatible. But this is not all there is to it: the order of `extends` matters. This is a known issue, and while it is disputable whether or not it is a bug, one should be aware of it, and code interfaces with this in mind.

https://bugs.php.net/bug.php?id=67270
https://bugs.php.net/bug.php?id=76361
https://bugs.php.net/bug.php?id=80785
To Top