Il n'y a rien de particulier à instancier des classes dérivées : DerivedClassName crée une nouvelle instance de la classe. Les références aux méthodes sont résolues comme suit : vous recherchez l'attribut de la classe correspondante, si nécessaire jusqu'à la fin de la chaîne de classe de base, et la référence à la méthode est valide si elle contient un objet fonction.
- Les classes dérivées peuvent remplacer les méthodes de leurs classes de base. Puisque les méthodes n'ont pas de privilèges spéciaux lors de l'appel d'autres méthodes du même objet, une méthode d'une classe de base qui appelle une autre méthode définie dans la même classe de base peut finir par appeler une méthode de la classe dérivée qui la remplace. (Pour les programmeurs C++++ : toutes les méthodes en Python sont essentiellement virtuelles.)
En fait, une méthode d'écrasement d'une classe dérivée étendra la méthode de la classe de base au même nom plutôt que de simplement la remplacer. Il existe un moyen simple d'appeler directement la méthode de classe de base : il suffit d'appeler BaseClassName.methodname.methodname.methodname(self, arguments). Ceci est parfois aussi utile pour les clients. (Notez que cela ne fonctionnera que si la classe de base est accessible en tant que BaseClassName dans le domaine global.)
Python a deux fonctions intégrées qui fonctionnent avec l'héritage :
Vous utilisez isinstance() pour contrôler le type d'un objet : isinstance(obj, int) n'est vrai que si obj.__class__ est un type int ou une classe dérivée.
Vous utilisez issubclass() pour vérifier l'héritage de la classe : issubclass(bool, int) est vrai parce que bool est une classe dérivée int, mais issubclass (float, int) est faux car float n'est pas une classe dérivée int.
9.5.1 Héritage multiple
Python supporte également une forme d'héritage multiple. Une définition de classe avec plusieurs classes de base ressemble à ceci :
classe DerivedClassName (Base1, Base2, Base3) :
<déclaration - 1>>>
.
.
.
<déclaration -N>>N
- Pour la plupart des cas, dans le cas le plus simple, la recherche des attributs hérités d'une classe mère peut être imaginée de cette façon : Tout d'abord en profondeur : tout d'abord, de gauche à droite, ne cherchez pas deux fois dans la même classe si la hiérarchie de classe la chevauche. Ainsi, si un attribut n'est pas trouvé dans DerivedClassName, il est recherché dans Base1, puis (récursivement) dans Base1 base classes, et s'il n'a pas été trouvé là, il est recherché dans Base2, et ainsi de suite.
En fait, c'est un peu plus complexe que ça, parce que l'ordre de résolution (MRO) de la méthode est modifié dynamiquement pour supporter les appels simultanés super(). Cette approche est connue dans d'autres langues sous le nom de méthode d'appel suivant (appel de la méthode suivante) et est plus puissante que le super appel qui existe dans les langues à héritage simple.
Il est nécessaire d'ordonner dynamiquement, puisque tous les cas d'héritage multiple ont une ou plusieurs relations diamant (où au moins une des classes mères est accessible par plusieurs chemins depuis la classe inférieure). Par exemple, toutes les classes héritent d'un objet et donc chaque cas d'héritage multiple offre de multiples façons d'atteindre l'objet. Pour éviter l'accès répété aux classes de base, l'algorithme dynamique linéarise l'ordre de recherche de sorte que l'ordre de gauche à droite défini dans chaque classe n'appelle chaque classe mère qu'une seule fois, monotone (ce qui signifie qu'une classe peut être héritée sans affecter le classement des parents). Toutes ces fonctionnalités permettent de concevoir des classes fiables et extensibles avec des héritages multiples.
Variables privées
- Les variables d'instance "privées" qui ne sont accessibles que dans l'objet n'existent pas en Python. Cependant, il y a une convention qui est suivie dans la plupart des codes Python : un nom commençant par un soulignement (par exemple _spam) doit être traité comme une partie non publique de l'API (que ce soit une fonction, une méthode ou un attribut de données). Il doit être traité comme des détails de mise en œuvre qui peuvent changer sans préavis.
- Puisqu'il y a une utilisation utile pour les attributs privés de la classe pour éviter les conflits de noms avec des noms définis par des sous-classes, il y a un support limité pour un tel mécanisme : le changement de nom. Chaque identificateur du module __spam (au moins deux soulignés initiaux, au plus un suivant) est remplacé dans le texte par _classname__spam, où classname est le nom de la classe courante (sans souligné initial). Le remplacement se produit quelle que soit la position syntaxique de l'identificateur, tant qu'il correspond à la définition de la classe.