Maison  >  Article  >  développement back-end  >  Pourquoi ne puis-je pas utiliser un sous-type dans le paramètre d’une méthode remplacée ?

Pourquoi ne puis-je pas utiliser un sous-type dans le paramètre d’une méthode remplacée ?

Barbara Streisand
Barbara Streisandoriginal
2024-11-13 16:32:02456parcourir

Why Can't I Use a Subtype in an Overridden Method's Parameter?

Covariance des paramètres dans les méthodes de remplacement

Dans la programmation orientée objet, le remplacement des méthodes permet aux sous-classes d'implémenter leurs propres versions des méthodes définies dans la superclasse . Cependant, lors de la substitution d'une méthode, les paramètres et le type de retour doivent être compatibles avec la déclaration de la méthode superclasse.

Dans le code donné, nous avons un scénario avec les interfaces suivantes :

<code class="php">interface Engine {
    function run();
}

interface HydroEngine extends Engine {
    function run();
}</code>

Et une structure similaire pour les classes :

<code class="php">interface Car {
    function setEngine(Engine $engine);
}

interface WaterCar extends Car {
    // This method is intended to override Car::setEngine()
    function setEngine(HydroEngine $engine);
}</code>

Le problème survient lorsque vous essayez de remplacer setEngine() dans WaterCar :

<code class="php">Fatal error: Declaration of WaterCar::setEngine() must be compatible with Car::setEngine(Engine $engine)</code>

Cette erreur se produit car le type de paramètre setEngine() dans WaterCar est HydroEngine, un sous-type de Engine, tandis que le type de paramètre dans la superclasse Car est Engine.

Le Principe de substitution de Liskov (LSP) régit de tels scénarios. Le LSP déclare qu'un sous-type (par exemple, HydroEngine) doit être substituable à son surtype (par exemple, Engine) sans interrompre la fonctionnalité du programme. Ce principe, cependant, ne s'applique pas aux types de paramètres dans les méthodes remplacées.

Dans ce cas, WaterCar n'implémente pas entièrement Car car il accepte un type de paramètre plus étroit dans setEngine(). En effet, une WaterCar ne peut accepter que des HydroEngines, alors qu'une Car peut accepter n'importe quel moteur. Cela viole LSP et rompt le contrat établi par la superclasse Car.

Pour résoudre ce problème, assurez-vous que les types de paramètres dans les méthodes remplacées sont compatibles avec les déclarations de la superclasse. Dans cet exemple, WaterCar::setEngine() pourrait être modifié comme suit :

<code class="php">function setEngine(Engine $engine): void;</code>

Cette modification maintient la compatibilité avec Car::setEngine() tout en permettant à WaterCar de se spécialiser dans l'acceptation des HydroEngines.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn