Question

J'ai développé une application YII. Et je me demande s'il est possible de déclarer dans le comportement du modèle une sorte de méthode "abstraite". Je sais qu'il est impossible d'utiliser directement la déclaration:

abstract class FantasticBehavior extends CActiveRecordBehavior
{
    public abstract function doSomethingFantastic();
}

Parce que nous avons besoin d'un instant de cette classe. Mais je sais aussi que Yii est pleine magie :)

Je veux juste faire de la classe des propriétaires pour redémarrer la méthode à partir du comportement par ordre obligatoire. Bien sûr, je peux utiliser l'interface en plus du comportement mais ...

Désolé si j'ai manqué quelque chose à dire ou que quelque chose n'est pas clair. Demandez simplement et je vais essayer d'expliquer ce que je veux dire.

Quelqu'un sait-il quelque chose à ce sujet?

Merci d'avance.

Mettre à jour

Je comprends que Yii n'est que PHP. Il n'étend pas PHP. C'est la superstructure dessus. Et il n'a pas de héritage multiple, car PHP ne le fait pas.

Je comprends que la méthode de comportement ne peut pas être déclarée en utilisant un mot-clé abstrait. C'est pourquoi j'ai écrit le mot "Résumé" en citations. Mais peu importe. Je sais comment fonctionnent les comportements.

Ma question était de savoir si je pouvais en quelque sorte obliger le modèle (par exemple, l'enfant de cactiveRecord) de déclarer une méthode.

Par exemple, pour mes fins, je peux faire quelque chose comme ceci:

class FantasticBehavior extends CActiveRecordBehavior
{
    public function doFantasticThings()
    {
        $this->owner->prepareForFantastic();
        // some code
    }
}

Par conséquent, si j'attache ce comportement à mon modèle et à l'appel de la méthode dofantasticThings, cette méthode essaiera d'appeler la méthode Prépare-Forfantastic à partir du modèle (propriétaire). Et si le modèle n'a pas de méthode Préparent pour la nouvelle exception déclarée, une nouvelle exception sera lancée car la méthode non déclarée est appelée.

On dirait que j'ai répondu à ma question moi-même :) qu'en pensez-vous?

Upd2

Oui, je sais que si nous n'appelons pas la méthode "abstraite", nous ne saurons pas qu'il n'est pas déclaré. C'est un «charme» de langues interprétables :) Nous ne savons pas s'il y a une erreur jusqu'à ce que le code soit exécuté. Cependant, cela serait génial si nous pouvions le savoir aussi plus tôt que possible. Par exemple, une fois par exemple de FantasticBehavior-Classe est attachée au modèle dont nous pourrions jeter un enfant CException Pour montrer quelles méthodes requises doivent être déclarées dans le modèle. Pour atteindre cela, nous pouvons utiliser quelque chose comme énuméré ci-dessous:

class FantasticBehavior extends CActiveRecordBehavior
{

    public function attach($owner)
    {

        if(!/*$owner has declared methods list this->abstractMethods*/)
        {
            throw new CAbstractMethodNotDecalared('....');
        }

        parent::attach($owner);     
    }

    public function abstractMethods()
    {
        return array('prepareForFantastic');
    }

}

Nous devons remplacer la méthode attach de la classe CBehavior et vérifiez si les méthodes "abstraites" déclarées. Méthode abstractMethods est utilisé pour obtenir la méthode de la liste "abstraite".

Je ne sais pas s'il y a attachBehavior L'événement existe. Si c'est le cas, nous pouvons l'utiliser au lieu de remplacer attach méthode.

En utilisant cette classe de base d'idées pour les comportements avec des méthodes "abstraites".

Que penses-tu de cela?

Peut-être qu'à l'avenir, je ferai l'extension pour YII et deviendrai célèbre et riche? :))

Était-ce utile?

La solution

Cela pourrait être un peu déroutant à expliquer ...

Non, vous ne pouvez pas "attacher" des méthodes abstraites à votre modèle cactiveRecord en utilisant Les comportements de Yii. Tout ce que les comportements font est quelques remplacements intelligents de __call(), __get() et __set() qui donne le illusion de l'héritage multiple. (C'est un bon article à ce sujet). Les comportements ne fournissent pas vrai Prise en charge des fonctionnalités "multiples successions" pour les fonctionnalités de la langue de base telles que les classes abstraites et les interfaces. Donc, si vous attachez ce comportement et ajoutez doSomethingFantastic() à ton CActiveRecord classe, vous obtiendrez toujours une erreur.

Tu boîte, bien sûr, déclarer les comportements abstraits que d'autres comportements étendent. Donc, si vous en avez créé un autre SuperFantasticBehavior Comportement qui s'est étendu FantasticBehavior et mis en œuvre doSomethingFantastic() dans ce, ça ira. Mais cela ne vous obligera pas à déclarer le doSomethingFantastic() Méthode dans le CActiveRecord lui-même.

Pour une compréhension un peu plus profonde: la façon dont Yii Ccomponent :: _ call () Le remplacement est structuré, lorsque vous appelez une méthode, il verra d'abord si l'un des comportements a cette méthode et appelez la méthode de la classe elle-même.

Le comportement semble cool au début (mixins!), Mais parfois il vaut mieux se rappeler que PHP est un langue d'héritage unique et garder est simple. ;)

METTRE À JOUR:

La différence est que si vous pouviez utiliser des méthodes abstraites dans ce cas, vous verriez une erreur "Classe doit implémenter la méthode" lorsque vous essayez d'exécuter votre code (n'importe quel Code), et votre IDE mettrait en évidence l'erreur. Il s'agit davantage d'une erreur temporelle "compile" (pas qu'il existe vraiment dans un Lang interprété comme PHP).

Au lieu de cela, vous verrez une erreur "méthode non déclaré" (comme vous le mentionnez) lors de l'exécution. Mais vous ne le verrez pas tant que cette méthode n'est pas appelée, ce qui signifie que vous n'obtenez pas ce joli avertissement précoce comme une définition abstraite vous donnerait. Et si cette méthode est jamais appelé, vous n'obtiendrez pas l'erreur, ce qui signifie qu'il n'est pas vraiment "obligeant" la déclaration de la même manière qu'un DEF abstrait.

Désolé si ma réponse initiale commençait à un niveau trop basique, je voulais juste être sûr qu'il n'y avait pas de malentendu. C'est une discussion intéressante et m'a fait réfléchir davantage à ce que fait vraiment une déclaration abstraite. Merci et heureux codage! :)

Acclamations

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top