Comment les interfaces PHP changent réellement le comportement des classes
P粉289775043
P粉289775043 2023-09-02 23:49:28
0
1
627
<p>Selon la documentation PHP, </p> <blockquote> <p>Les interfaces d'objet vous permettent de créer du code qui spécifie les méthodes qu'une classe doit implémenter sans définir comment ces méthodes sont implémentées. </p> </blockquote> <p>Ainsi, une interface est comme une classe avec des méthodes prédéfinies auxquelles il faut encore accéder en utilisant la notation <code>-></code> <p>Cependant, l'interface ArrayAccess permet d'accéder aux objets sous forme de tableaux. Les objets sont accessibles en utilisant <code>$object->property</code> et <code>$object["property"]</code></p> <p>Je ne comprends pas comment ArrayAccess permet de modifier la syntaxe de l'objet. J'ai écrit un morceau de code pour essayer de reproduire l'effet de la méthode <code>ArrayAccess</code>un seul</em>, mais cela renvoie l'erreur</p> <pre class="brush:php;toolbar:false;">// Utilisation de l'interface PHP ArrayAccess espace de noms A { classe maclasse implémente ArrayAccess { public function offsetExists($offset) { return true } fonction publique offsetGet($offset) { // changement de comportement return $this->{$offset} ?? } fonction publique offsetSet ($ offset, $ valeur) {} fonction publique offsetUnset($offset) {} } $maclasse = new maclasse(); $maclasse->access = 'Interface'; echo $maclasse['accès']; // "Interface" } ; //Essayer d'implémenter ma propre interface ArrayAccess espace de noms B { interface MonArrayAccess { fonction publique offsetGet($offset); } la classe maclasse implémente MyArrayAccess { fonction publique offsetGet($offset) { // change de comportement return $this->{$offset} ?? } } $maclasse = new maclasse(); $maclasse->access = 'Interface'; echo $myclass['access']; // Erreur fatale : erreur non détectée : impossible d'utiliser un objet de type Bmyclass comme tableau } ≪/pré> <p>S'il vous plaît, aidez-moi à l'expliquer correctement. Merci</p>
P粉289775043
P粉289775043

répondre à tous(1)
P粉702946921

Je ne dis pas que les interfaces "changent le comportement d'une classe", je dis que les interfaces facilitent étendre les fonctionnalités de classe.

Pour comprendre l'interface, en tant que concept de programmation orientée objet, nous devons d'abord comprendre quel problème elle veut résoudre.

Quel problème « Interface » vise-t-il à résoudre ?

Une interface est un contrat. Voici comment implémenter duck-typing en PHP. Vous devez penser du point de vue d'un rédacteur de bibliothèque qui souhaite exposer les fonctionnalités aux autres. Par exemple,

class Greeter
{
    public function greet($person)
    {
        echo "Hello, {$person->getName()}!\n";
    }
}

Pour garantir que les usagers de la bibliothèque connaissent la méthode $person 需要有 getName() 方法,您可以创建一个类 Person > 有一个 getName(). Utilisez ensuite les déclarations de type pour détecter les erreurs potentielles lorsque le code est résolu.

class Greeter
{
    public function greet(Person $person)
    {
        echo "Hello, {$person->getName()}!\n";
    }
}

class Person
{
    public string $name;
    public function getName(): string
    {
        return $this->name;
    }
}

Supposons qu'il existe une autre bibliothèque qui nourrit les objets avec de la nourriture :

class Feeder {
    public function feed(Eater $eater, string $food) {
        $eater->eat($food);
    }
}

class Animal {
    private $stomach = [];
    public function eat(string $food) {
        $stomach = $food;
    }
}

Considérez ceci...

Maintenant, disons que l'utilisateur souhaite écrire une fonction qui peut à la fois manger et dire bonjour Pet 类。用户不想仅仅为了 Pet Réécrivez ces fonctions.

Comment écrire Pet 以便同时使用 GreeterFeeder bibliothèque ?

Peut-être que c'est le cas ?

class Pet extends Person, Animal {
}

Malheureusement, PHP ne prend pas en charge l'héritage multiple. Une classe ne peut avoir qu'une seule classe. Le code ci-dessus n'est pas valide. Ainsi, dans la situation actuelle, les utilisateurs ne peuvent utiliser qu’une seule des bibliothèques. 扩展

De plus, « nom » peut être un concept très différent pour différentes choses (par exemple, on peut utiliser la méthode

. getName() 返回 $first_name$last_name 代码>)。您的库类中可能没有合理的默认实现 getName()

Ainsi, en tant que rédacteur de bibliothèque, vous souhaitez que sa bibliothèque soit aussi flexible que possible pour les utilisateurs. Que pouvez-vous faire?

Comment résoudre ce problème en utilisant les "interfaces" en PHP ?

Une interface est une déclaration de signatures de méthodes. Il s'agit d'un moyen rapide de déclarer les exigences de la bibliothèque sans exigences concrètes de classe/d'héritage.

À l'aide des interfaces, vous pouvez réécrire les deux bibliothèques comme ceci :

bibliothèqueGreeter
class Greeter {
    public function greet(Namer $namer) {
        echo "Hello, {$namer->getName()}!\n";
    }
}

interface Namer {
    public function getName(): string;
}

bibliothèqueFeeder
class Feeder {
    public function feed(Eater $eater, string $food) {
        $eater->eat($food);
    }
}

interface Eater {
    public function eat(string $food);
}

Pas besoin d'une classe spécifique (ou d'un héritage de classe parent), une classe peut implémenter plusieurs interfaces. La

classe suivante est donc tout à fait valide en PHP : Pet

class Pet implements Namer, Eater {
    private array $stomach = [];
    private string $name = '';

    public function __construct(string $name)
    {
        $this->name = $name;
    }

    /**
     * Implements Namer.
     */
    public function getName(): string
    {
        return $this->name;
    }

    /**
     * Implements Eater.
     */
    public function eat(string $food)
    {
        $this->stomach[] = $food;
    }
}

$greeter = new Greeter();
$feeder = new Feeder();
$pet = new Pet('Paul');

$greeter->greet($pet);
$feeder->feed($pet, 'a biscuit');
Maintenant, les objets de cette

classe peuvent être utilisés avec la bibliothèque Pet 类的对象可以与 Greeter 库和 Feeder et la bibliothèque

.

ArrayAccess

Et l'interface ?

L'interface ArrayAccess

n'est pas déclarée par un rédacteur de bibliothèque d'interface tiers, mais est écrite par un rédacteur PHP principal. Le rédacteur principal de PHP fournit un support plus approfondi pour cela. 🎜

Un peu comme les interfaces que nous avons mentionnées précédemment, PHP fournit des fonctionnalités aux classes qui l'implémentent. Mais au lieu de fournir l'GreeterFeeder exemple ci-dessus, le noyau PHP fournit sucre syntaxique pour une classe qui implémente ArrayAccess. Cela signifie que vous pouvez utiliser un code plus simple lorsque vous traitez avec des classes qui implémentent l'interface AccessAccess.

Dans l'exemple officiel,

<?php
class Obj implements ArrayAccess {
    private $container = array();

    public function __construct() {
        $this->container = array(
            "one"   => 1,
            "two"   => 2,
            "three" => 3,
        );
    }

    public function offsetSet($offset, $value) {
        if (is_null($offset)) {
            $this->container[] = $value;
        } else {
            $this->container[$offset] = $value;
        }
    }

    public function offsetExists($offset) {
        return isset($this->container[$offset]);
    }

    public function offsetUnset($offset) {
        unset($this->container[$offset]);
    }

    public function offsetGet($offset) {
        return isset($this->container[$offset]) ? $this->container[$offset] : null;
    }
}

Si vous les avez implémentés, remplacez-les par :

$obj = new Obj;
$obj->offsetSet(10, "hello");
$obj->offsetSet(11, "world");
if ($obj->offsetUnset(12)) {
    $obj->offsetUnset(12);
}
echo $obj->offsetGet(11);

Vous pouvez utiliser $obj avec une syntaxe de type tableau pour rendre votre code plus court :

$obj = new Obj;

$obj[10] = "hello";
$obj[11] = "world";
if (isset($obj[12])) {
    unset($obj[12]);
}
echo $obj[11];
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal