<HS>Barbara Liskov, elle pas il :p</HS>
Je considère par référence, et des méthodes virtuelles, sinon le LSP n'a aucun sens (méthodes non redéfinisables et pas de polymorsphisme => pas de LSP)
Je vais prendre un exemple :
1 2 3
|
class A { public: virtual void foo() {} };
class B : public A { private: virtual void foo() {} }; |
Je vais considérer la propriété P="peut recevoir le message foo", qui est donc simplement vérifiable à la compilation en tentant d'appeler foo sur un objet.
Soit la fontion :
void bar(A& a) { a.foo(); }
L'écriture de ce code est envisageable, le passage par référence m'assure le polymorphisme, et la présence de foo dans l'espace publique de A couplé au LSP m'assure que ce code doit être fonctionnel pour tout objet d'un sous-type de A (B en particulier).
Maintenant considérons un première portion de code de ce type :
Ce code ne compile pas, on constate donc que la propriété P n'est pas vraie pour l'objet b1, donc le LSP est violé.
Encuite un second passage :
On constate que ce code compile, donc que la proriété P est vraie pour l'objet nommé 'a' dans le corps de la fonction, même quand celui-ci provient d'un B, on en conclu donc que le LSP est vraie dans le corps de la fonction.
Tu noteras aussi que le fait de pouvoir passer (et que ca fonctionne) un objet de type B à la méthode bar qui attend une référence sur A valide le LSP si l'on considère l'autre définition (la non formel). Et que c'est quand même bien le but recherché (à ma connaisance) par le LSP que d'assurer que ce genre de chose soit possible, et que la définition formel est juste là pour avoir quelque chose de plus "propre".
C'est donc ceci que je considère comme une ambiguité, le fait que le LSP soit violé du point de vue formel, mais correct là ou il est utile (dans le corps des fonctions qui profite du polymorphisme).
Partager