web-dev-qa-db-fra.com

Les méthodes privées dans les sous-classes violent-elles le principe de substitution de Liskov?

J'ai cherché cette question mais je n'ai pas trouvé de bonne réponse pour mon cas.

Supposons que j'ai une superclasse pour un prêt bancaire avec des propriétés Amount et InterestRate.

public class BankLoan{
   public double Amount {get; set;}
   public double InterestRate {get; set;}
}

Ensuite, je crée une classe dérivée appelée Smallloan, qui aura une variable InterestRate basée sur son montant.

public class SmallLoan{
   public SmallLoan(){
     InterestRate = CalculateInterest();
   }

   private double CalculateInterest(){
      if(Amount < 100)
         return 0.10;
      else
         return 0.05;
   }
}

Cela violerait-il le LSP? Je penserais que cela ne le fait pas, car même si une instance de SmallLoan tente d'appeler CalculateInterest en dehors de la définition de la classe, il va lancer une erreur, non liée à la substitution mais simplement parce qu'il a un autre modificateur d'accès différent. Même si seulement BankLoan existait et qu'il avait la même méthode privée, un appel à l'extérieur entraînerait également une erreur.

Mais je peux voir comment certaines personnes diraient que la présence de l'erreur en général est une violation du principe.

Enfin: je suis conscient que ces classes pourraient ne pas être les meilleures et les plus brillantes implémentations d'héritage ou même de la conception de classe de base, mais la question ne se pose pas de cela, je veux simplement savoir si des méthodes privées sont une violation du LSP, et je choisi de l'illustrer avec cet exemple très simple.

3
ThePorcius

Si vous utilisiez un objet de banque de banque dans le code quelque part, la référence pourrait être remplacée par une implémentation de SmallLoan (puisque un petit -loan est une banque de banque) et la demande elle-même ne saurait aucune différence. Les méthodes privées à l'intérieur de la mise en œuvre importeraient peu.

Toutefois, si vous avez un objet de petite taille dans le code, vous ne seriez pas en mesure de remplacer la référence par une implémentation de banque de banque (puisqu'un Bankloan n'est pas un petit). C'est là que la violation se produirait. Les deux instances ne peuvent pas se remplacer également.

Afin de tirer parti du LSP, vous voulez plutôt quelque chose dans le sens d'une interface, telle qu'un Iloan, qui décrirait le comportement/les propriétés que toutes les implémentations auraient besoin. À ce stade, une référence iloenne pourrait être remplacée par tout ce qui implémente l'interface iloenne. Si Smallloan et Bankloan ont tous deux mis en œuvre l'interface, ils pourraient facilement se remplacer au niveau de référence. Les méthodes privées n'auraient aucun effet sur cela.

Je me trompe peut-être sur mon interprétation, mais le LSP se soucie d'avoir des comportements/propriétés attendus, plutôt que sur la manière dont ils sont mis en œuvre.

0
Brian Place

Clairement si j'ai un objet avec une propriété "intérêt" avec un getter et un setter, je m'attends à ce que l'appelant le Setter puisse modifier la valeur renvoyée par le getter et le calcul des intérêts. Votre classe "smallloan" ne répond pas à ce comportement est-ce que cela se comporte très étrangement. C'est là que votre violation est.

Vous pourriez avoir une baseClass "genericloan" avec seulement un getteur public et un ensemble protégé pour le taux d'intérêt, deux sous-classes "Bankloan" et "Smallloan", avec "Bankloan" ayant un setter public. Vous ne pouvez pas définir le taux d'intérêt sur un prêt générique car toutes les sous-classes ne le comprennent pas.

Ps. Les méthodes privées ou les propriétés ne sont que des détails de mise en œuvre. Ils n'ont rien à voir avec le LSP du tout. Les méthodes publiques dans une sous-classe n'ont toujours rien à voir avec le LSP, car elles ne peuvent être appelées que si vous avez une référence à un objet de sous-classe. À un moment donné, DOIT être une différence, sinon pourquoi voudriez-vous une sous-classe s'il est exactement identique à la classe de base?

0
gnasher729

Aucune méthode privée ne casse pas la LSP car la sous-classe contient toujours les méthodes et attributs de la classe de base, nous pouvons donc toujours utiliser Smallloan comme Bankloan mais pas Markloan comme Smallloan sans utiliser de couler

0
Richard Bamford