Programmation orientée objet Python (2)

PHP中文网
Libérer: 2017-07-09 18:13:53
original
1249 Les gens l'ont consulté

1. Héritage et dérivation

Nous avons dit plus haut que tout en Python est un objet. Nous avons extrait les caractéristiques et compétences communes des objets et obtenu le concept de classes. Il existe également des caractéristiques communes entre les classes. Nous pouvons extraire des compétences et des caractéristiques communes à partir de classes ayant des caractéristiques et des compétences communes, appelées classes parentales.

Par exemple, les enseignants et les élèves ont des noms, des âges, des anniversaires, des sexes, etc., et ils peuvent marcher, parler et manger. . . On peut résumer une classe « humaine » composée d'enseignants et d'élèves, appelée classe parent. Ensuite, les enseignants et les élèves sont des sous-classes de la classe « humaine ». La sous-classe hérite de la classe parent et possède les caractéristiques et méthodes de la classe parent.

L'héritage est une relation entre ce qui « est » et quelque chose. L'héritage est une méthode de génération de nouvelles classes, et bien sûr, le but est de réduire la réutilisation du code.

La forme de base de l'héritage est :

<span style="color: #0000ff">class</span><span style="color: #000000"> People:
    </span><span style="color: #0000ff">pass</span>
<span style="color: #0000ff">class</span> Student(People):<span style="color: #008000">#</span><span style="color: #008000">People称为基类或者父类</span>
    <span style="color: #0000ff">pass</span>
Copier après la connexion

L'héritage multiple est pris en charge en Python et une sous-classe peut hériter de plusieurs classes parent

Nous pouvons afficher toutes les classes parents héritées via la méthode __bases__, qui renverra un tuple.

<span style="color: #0000ff">class</span><span style="color: #000000"> People:
    </span><span style="color: #0000ff">pass</span>
<span style="color: #0000ff">class</span><span style="color: #000000"> Animals:
    </span><span style="color: #0000ff">pass</span>
<span style="color: #0000ff">class</span><span style="color: #000000"> Student(People,Animals):
    </span><span style="color: #0000ff">pass</span>

<span style="color: #0000ff">print</span>(Student.<span style="color: #800080">__bases__</span>)<span style="color: #008000">#</span><span style="color: #008000">(<class '__main__.People'>, <class '__main__.Animals'>)</span>
<span style="color: #0000ff">print</span>(People.<span style="color: #800080">__bases__</span>)<span style="color: #008000">#</span><span style="color: #008000">(<class 'object'>,)</span>
Copier après la connexion

Vous pouvez voir que dans la classe parent People, une classe d'objet est également héritée par défaut. C'est la différence entre les classes de nouveau style et les classes classiques :
Toute classe qui hérite de la classe d'objet et de ses sous-classes est appelée. Les classes new-style qui n'héritent pas de la classe d'objet sont appelées classes classiques.

Dans Python 3, la valeur par défaut est les classes de nouveau style, tandis que dans Python 2.X, la valeur par défaut est les classes classiques

Comment l'héritage peut-il réduire le code ? Voir exemple

<span style="color: #0000ff">class</span><span style="color: #000000"> People:
    </span><span style="color: #0000ff">def</span> <span style="color: #800080">__init__</span><span style="color: #000000">(self,name,age):
        self.name</span>=<span style="color: #000000">name
        self.age</span>=<span style="color: #000000">age
    </span><span style="color: #0000ff">def</span><span style="color: #000000"> walk(self):
        </span><span style="color: #0000ff">print</span>(<span style="color: #800000">'</span><span style="color: #800000">%s is walkig</span><span style="color: #800000">'</span>%<span style="color: #000000">self.name)

</span><span style="color: #0000ff">class</span><span style="color: #000000"> Teacher(People):
    </span><span style="color: #0000ff">def</span> <span style="color: #800080">__init__</span><span style="color: #000000">(self,name,age,level):
        People.</span><span style="color: #800080">__init__</span><span style="color: #000000">(self,name,age)
        self.level</span>=<span style="color: #000000">level

t1</span>=Teacher(<span style="color: #800000">'</span><span style="color: #800000">zhang</span><span style="color: #800000">'</span>,18,10<span style="color: #000000">)
</span><span style="color: #0000ff">print</span>(t1.level) <span style="color: #008000">#</span><span style="color: #008000">10</span>
<span style="color: #0000ff">print</span>(t1.name)  <span style="color: #008000">#</span><span style="color: #008000">zhang          子类可以用父类定义的属性</span>
t1.walk()   <span style="color: #008000">#</span><span style="color: #008000">zhang is walking   子类无需定义就可以用父类的方法</span>
<span style="color: #0000ff">print</span>(issubclass(Teacher,People))   <span style="color: #008000">#</span><span style="color: #008000">True查看Teacher类是不是People类的子类</span>
Copier après la connexion

Comme vous pouvez le voir dans l'exemple ci-dessus, la classe Teacher hérite de la classe People de la classe parent, mais Teacher a son propre niveau d'attribut unique. Les sous-classes peuvent également définir leurs propres méthodes uniques, qui peuvent même chevaucher les méthodes du parent. nom de la classe, mais l'exécution sera basée sur la définition de la sous-classe.

C'est ce qu'on appelle la dérivation

2. Combinaison

L'héritage résout le problème de ce qui « est » quelque chose. Ensuite, il existe un autre scénario dans lequel tout a quelque chose. Par exemple, l'enseignant a un anniversaire, l'élève a également un anniversaire, et l'anniversaire a des attributs tels que l'année, le mois. et le jour. Si chaque classe l'écrit, alors c'est du code en double. Mais les étudiants et les enseignants ne peuvent pas être autorisés à hériter de la classe d'anniversaire. C'est ici que la combinaison est utilisée. La combinaison consiste à résoudre le problème de ce qui « a » quelque chose. Voir exemple

<span style="color: #0000ff">class</span><span style="color: #000000"> Date:
    </span><span style="color: #0000ff">def</span> <span style="color: #800080">__init__</span><span style="color: #000000">(self,year,mon,day):
        self.year</span>=<span style="color: #000000">year
        self.mon</span>=<span style="color: #000000">mon
        self.day</span>=<span style="color: #000000">day
    </span><span style="color: #0000ff">def</span><span style="color: #000000"> tell_birth(self):
        </span><span style="color: #0000ff">print</span>(<span style="color: #800000">'</span><span style="color: #800000">出生于%s年%s月%s日</span><span style="color: #800000">'</span>%<span style="color: #000000">(self.year,self.mon,self.day))

</span><span style="color: #0000ff">class</span><span style="color: #000000"> Teacher:
    </span><span style="color: #0000ff">def</span> <span style="color: #800080">__init__</span><span style="color: #000000">(self,name,age,year,mon,day):
        self.name</span>=<span style="color: #000000">name
        self.age</span>=<span style="color: #000000">age
        self.birth</span>=<span style="color: #000000">Date(year,mon,day)
t</span>=Teacher(<span style="color: #800000">'</span><span style="color: #800000">egon</span><span style="color: #800000">'</span>,19,2010,10,10<span style="color: #000000">)
</span><span style="color: #0000ff">print</span>(t.birth)          <span style="color: #008000">#</span><span style="color: #008000"><__main__.Date object at 0x0000017E559380F0></span>
t.birth.tell_birth()    <span style="color: #008000">#</span><span style="color: #008000">出生于2010年10月10日</span>
Copier après la connexion

Quoi ? Trop de paramètres ? *Apprenez les *arguments, tant que vous êtes heureux

<span style="color: #008080"> 1</span> <span style="color: #0000ff">class</span><span style="color: #000000"> Date:
</span><span style="color: #008080"> 2</span>     <span style="color: #0000ff">def</span> <span style="color: #800080">__init__</span><span style="color: #000000">(self,year,mon,day):
</span><span style="color: #008080"> 3</span>         self.year=<span style="color: #000000">year
</span><span style="color: #008080"> 4</span>         self.mon=<span style="color: #000000">mon
</span><span style="color: #008080"> 5</span>         self.day=<span style="color: #000000">day
</span><span style="color: #008080"> 6</span>     <span style="color: #0000ff">def</span><span style="color: #000000"> tell_birth(self):
</span><span style="color: #008080"> 7</span>         <span style="color: #0000ff">print</span>(<span style="color: #800000">'</span><span style="color: #800000">出生于%s年%s月%s日</span><span style="color: #800000">'</span>%<span style="color: #000000">(self.year,self.mon,self.day))
</span><span style="color: #008080"> 8</span> 
<span style="color: #008080"> 9</span> <span style="color: #0000ff">class</span><span style="color: #000000"> Teacher:
</span><span style="color: #008080">10</span>     <span style="color: #0000ff">def</span> <span style="color: #800080">__init__</span>(self,name,age,*<span style="color: #000000">args):
</span><span style="color: #008080">11</span>         self.name=<span style="color: #000000">name
</span><span style="color: #008080">12</span>         self.age=<span style="color: #000000">age
</span><span style="color: #008080">13</span>         self.birth=Date(*<span style="color: #000000">args)
</span><span style="color: #008080">14</span> t=Teacher(<span style="color: #800000">'</span><span style="color: #800000">egon</span><span style="color: #800000">'</span>,19,2010,10,10<span style="color: #000000">)
</span><span style="color: #008080">15</span> <span style="color: #0000ff">print</span>(t.birth)          <span style="color: #008000">#</span><span style="color: #008000"><__main__.Date object at 0x0000017E559380F0></span>
<span style="color: #008080">16</span> t.birth.tell_birth()    <span style="color: #008000">#</span><span style="color: #008000">出生于2010年10月10日</span>
Copier après la connexion
Afficher le code

3. Classes et interfaces abstraites

L'héritage a deux utilisations : 1. Réutilisation du code, la sous-classe hérite de la méthode de la classe parent

2. Déclarez qu'une sous-classe est compatible avec une classe parent et définissez une classe d'interface Interface. La classe d'interface définit certains noms d'interface (c'est-à-dire des noms de fonctions) et n'implémente pas les fonctions de l'interface. classe d'interface et implémente les fonctions dans l'interface

Il est à noter qu'il n'y a pas de mot-clé pour interface en Python. On ne peut qu'imiter les fonctions de l'interface.
Par exemple, en Python, tout est un fichier, donc le programme est un fichier, le matériel. est un fichier, tout comme les documents texte. Nous savons ce qu'est un fichier, c'est-à-dire qu'il peut être lu et écrit. Les programmes et les documents texte doivent tous avoir des fonctions de lecture et d'écriture

.
<span style="color: #0000ff">class</span><span style="color: #000000"> Interface:
    </span><span style="color: #0000ff">def</span><span style="color: #000000"> read(self):
        </span><span style="color: #0000ff">pass</span>
    <span style="color: #0000ff">def</span><span style="color: #000000"> write(self):
        </span><span style="color: #0000ff">pass</span>
    
    
<span style="color: #0000ff">class</span><span style="color: #000000"> Txt(Interface):
    </span><span style="color: #0000ff">def</span><span style="color: #000000"> read(self):
        </span><span style="color: #0000ff">print</span>(<span style="color: #800000">'</span><span style="color: #800000">文本文档的读取方式</span><span style="color: #800000">'</span><span style="color: #000000">)
    </span><span style="color: #0000ff">def</span><span style="color: #000000"> write(self):
        </span><span style="color: #0000ff">print</span>(<span style="color: #800000">'</span><span style="color: #800000">文本文档的写入方式</span><span style="color: #800000">'</span><span style="color: #000000">)
        
</span><span style="color: #0000ff">class</span><span style="color: #000000"> Sata(Interface):
    </span><span style="color: #0000ff">def</span><span style="color: #000000"> read(self):
        </span><span style="color: #0000ff">print</span>(<span style="color: #800000">'</span><span style="color: #800000">硬盘文件的读取方式</span><span style="color: #800000">'</span><span style="color: #000000">)
    </span><span style="color: #0000ff">def</span><span style="color: #000000"> write(self):
        </span><span style="color: #0000ff">print</span>(<span style="color: #800000">'</span><span style="color: #800000">硬盘文件的写入方式</span><span style="color: #800000">'</span><span style="color: #000000">)

</span><span style="color: #0000ff">class</span><span style="color: #000000"> process(Interface):
    </span><span style="color: #0000ff">def</span><span style="color: #000000"> read(self):
        </span><span style="color: #0000ff">print</span>(<span style="color: #800000">'</span><span style="color: #800000">进程数据的读取方式</span><span style="color: #800000">'</span><span style="color: #000000">)
    </span><span style="color: #0000ff">def</span><span style="color: #000000"> write(self):
        </span><span style="color: #0000ff">print</span>(<span style="color: #800000">'</span><span style="color: #800000">进程数据的写入方式</span><span style="color: #800000">'</span>)
Copier après la connexion
Afficher le code

这么做的意义就是:我们不需要知道子类有什么具体的方法,既然他们继承了文件类,那他们就是文件,那他们就有读和写这两个功能

父类限制了子类子类必须有read和write这两个方法,而且名字也必须一样(当然现在只是我们主观上的限制,一会我们说完抽象类,就可以从代码级别上限制了),这样就实现了统一,模拟了接口的概念,这就是归一化设计。在归一化设计中,只要是基于一个接口设计的类,那么所有的这些类实例化出来的对象,在用法上是一样的

我们再来说一下抽象类:

Python中的抽象类需要导入一个模块来实现。抽象类只能被继承,不能被实现

抽象类的写法:

<span style="color: #0000ff">import</span><span style="color: #000000"> abc
</span><span style="color: #0000ff">class</span> File(metaclass=<span style="color: #000000">abc.ABCMeta):
    @abc.abstractmethod
    </span><span style="color: #0000ff">def</span><span style="color: #000000"> read(self):
        </span><span style="color: #0000ff">pass</span><span style="color: #000000">
    @abc.abstractmethod
    </span><span style="color: #0000ff">def</span><span style="color: #000000"> write(self):
        </span><span style="color: #0000ff">pass</span>
<span style="color: #008000">#</span><span style="color: #008000">父类使用了抽象类,那子类就必须继承父类的方法,而且名字也必须一样</span><span style="color: #008000">
#</span><span style="color: #008000">这样就实现了代码级别的限制</span>

<span style="color: #0000ff">class</span><span style="color: #000000"> Txt(File):
    </span><span style="color: #0000ff">def</span><span style="color: #000000"> read(self):
        </span><span style="color: #0000ff">print</span>(<span style="color: #800000">'</span><span style="color: #800000">文本文档的读取方式</span><span style="color: #800000">'</span><span style="color: #000000">)
    </span><span style="color: #0000ff">def</span><span style="color: #000000"> write(self):
        </span><span style="color: #0000ff">print</span>(<span style="color: #800000">'</span><span style="color: #800000">文本文档的写入方式</span><span style="color: #800000">'</span>)
Copier après la connexion

 

4.继承的实现原理

1)继承顺序:

python支持多继承,当一个类继承多个父类时,继承顺序是怎样的呢?这个顺序在新式类和经典类中是不一样的。

在新式类中,继承顺序是广度优先,在经典类中是深度优先,举个栗子:

图不重要,看内容
在这个图中,H是子类,H继承E,F,G,E,F,G,又分别继承B,C,D,B,C,D,同时继承A

在新式类中的顺序是:H E B F C G D A 

在经典类中的顺序是:H E B A F C G D

2)继承原理:

当我们定义一个类后,Python就会根据上面的继承规律解析出一个继承顺序的列表(MRO列表),可以通过mro()查看,但是这个方法只有在新式类中才有,经典类没有

mro

 

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!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal