Maison  >  Article  >  développement back-end  >  Un article pour comprendre ce qu'est l'héritage en Python orienté objet

Un article pour comprendre ce qu'est l'héritage en Python orienté objet

爱喝马黛茶的安东尼
爱喝马黛茶的安东尼avant
2019-08-28 17:40:022940parcourir

Un article pour comprendre ce qu'est l'héritage en Python orienté objet

1. Qu'est-ce que l'héritage ?

L'héritage fait référence à la relation entre les classes, une relation entre ce qui est, et l'une de ses fonctions est de résoudre le problème de la réutilisation du code.

L'héritage est un moyen de créer une nouvelle classe. En Python, une nouvelle classe peut hériter d'une ou plusieurs classes parentes. La classe parent peut également être appelée une classe de base ou une super classe. Appelé classe dérivée ou sous-classe, l'héritage est divisé en héritage unique et héritage multiple.

class ParentClass1: #定义父类
    pass
class ParentClass2: #定义父类
    pass
class SubClass1(ParentClass1): #单继承,基类是ParentClass1,派生类是SubClass
    pass
class SubClass2(ParentClass1,ParentClass2): #python支持多继承,用逗号分隔开多个继承的类
    pass
print(Son1.__bases__)  # 查看所有继承的父类
print(Son2.__bases__)
===============
(<class &#39;__main__.Father1&#39;>,)
(<class &#39;__main__.Father1&#39;>, <class &#39;__main__.Father2&#39;>)

2. Héritage et abstraction

L'abstraction est divisée en deux niveaux :

1. Les parties qui comparent Obama et Messi Extraient en catégories ;

2. Extrayez les parties les plus similaires des trois catégories d'humains, de porcs et de chiens dans les catégories parentales.

Le rôle principal de l'abstraction est de diviser les catégories (ce qui peut isoler les préoccupations et réduire la complexité)

Un article pour comprendre ce quest lhéritage en Python orienté objet

Héritage :

est basé sur le résultat de l'abstraction. Pour l'implémenter via un langage de programmation, vous devez d'abord passer par le processus d'abstraction avant de pouvoir exprimer la structure abstraite par héritage.

L'abstraction n'est qu'une action ou une technique en cours d'analyse et de conception, à travers laquelle des cours peuvent être obtenus.

Un article pour comprendre ce quest lhéritage en Python orienté objet

class animal():   # 定义父类
    country  =  &#39;china&#39;     # 这个叫类的变量
    def __init__(self,name,age):
        self.name=name   # 这些又叫数据属性
        self.age=age
    def walk(self):         # 类的函数,方法,动态属性
        print(&#39;%s is walking&#39;%self.name)
    def say(self):
        pass
class people(animal):  # 子类继承父类
    pass
class pig(animal):    # 子类继承父类
    pass
class dog(animal):  # 子类继承父类
    pass
aobama=people(&#39;aobama&#39;,60)   # 实例化一个对象
print(aobama.name)
aobama.walk()
===================
aobama
aobama is walking

3. Dérivé

1. Générez une sous-classe basée sur la classe parent, et la sous-classe générée est appelée type dérivé. .

2. Les méthodes qui ne sont pas trouvées dans la classe parent se trouvent dans la sous-classe. Ces méthodes sont appelées méthodes dérivées.

3. Les méthodes qui existent dans la classe parent et qui existent également dans la sous-classe sont appelées réécriture de méthodes (c'est-à-dire réécriture des méthodes dans la classe parent).

Recommandations associées : "Tutoriel vidéo Python"

Exemple 1

class Hero:
    def __init__(self, nickname,
                 aggressivity,
                 life_value):
        self.nickname = nickname
        self.aggressivity = aggressivity
        self.life_value = life_value
    def attack(self, enemy):
        enemy.life_value -= self.aggressivity
class Garen(Hero):   # 子类继承  hero 父类
    camp=&#39;Demacia&#39;   # 子类衍生出的变量
    def attack(self, enemy):   # 跟父类的 attack 重名,对象调用的时候以子类的为准
        pass
    def fire(self):    # 父类没有 fire,这里 fire 属于派生出来的东西
        print(&#39;%s is firing&#39; %self.nickname)
class Riven(Hero):
    camp=&#39;Noxus&#39;
g1=Garen(&#39;garen&#39;,18,200)
r1=Riven(&#39;rivren&#39;,18,200)
# print(g1.camp)
# print(r1.camp)
# g1.fire()
g1.attack(g1)

Exemple 2

class Hero:
    def __init__(self, nickname,aggressivity,life_value):
        self.nickname = nickname
        self.aggressivity = aggressivity
        self.life_value = life_value
    def attack(self, enemy):
        print(&#39;Hero attack&#39;)
class Garen(Hero):
    camp = &#39;Demacia&#39;
    def attack(self, enemy): #self=g1,enemy=r1
        # self.attack(enemy) #g1.attack(r1),这里相当于无限递归
        Hero.attack(self,enemy)  # 引用 父类的 attack,对象会去跑 父类的 attack
        print(&#39;from garen attack&#39;)  # 再回来这里
    def fire(self):
        print(&#39;%s is firing&#39; % self.nickname)
class Riven(Hero):
    camp = &#39;Noxus&#39;
g1 = Garen(&#39;garen&#39;, 18, 200)
r1 = Riven(&#39;rivren&#39;, 18, 200)
g1.attack(r1)
# print(g1.camp)
# print(r1.camp)
# g1.fire()

4. Et la réutilisabilité

Réutilisabilité :

Méthode 1 : Réutiliser les attributs sans héritage, et nommer les attributs de la classe à utiliser.

class Hero:
    def __init__(self,nickname,gongji,life):
        self.nickname=nickname
        self.gongji=gongji
        self.life=life
    def attack(self,obj):
        print(&#39;from Hero attack&#39;)
class Garen:
    def __init__(self,nickname,gongji,life,script):
        Hero.__init__(self,nickname,gongji,life)   # 这里引用Hero类的 init,不用再自己从新定义一遍 init
        self.script=script   # 父类 init 没有 script,这里是新加进来的属性
    def attack(self,obj):  # 在这里自己定义新的 attack,不再使用父类的 attack
        print(&#39;from Garen attack&#39;)
    def fire(self):  # 在这里定义新的功能
        print(&#39;from Garen fire&#39;)
g1=Garen(&#39;garen&#39;,18,200,&#39;人在塔在&#39;)
print(g1.script)
人在塔在

Astuce : créez une nouvelle classe en utilisant une classe existante, réutilisant ainsi une partie ou même la plupart des logiciels existants, économisant ainsi considérablement la charge de travail de programmation. C'est ce que l'on appelle souvent la réutilisation des logiciels. classes, vous pouvez également en hériter d'autres, telles que la bibliothèque standard, pour personnaliser de nouveaux types de données. Cela raccourcit considérablement le cycle de développement logiciel, ce qui est d'une grande importance pour le développement de logiciels à grande échelle.

Remarque : Pour les références d'attribut comme g1.life, la vie sera trouvée d'abord à partir de l'instance, puis de la classe, puis de la classe parent... jusqu'à la classe parent de niveau supérieur.

Méthode 2 : Par héritage

Exemple 1

class Hero():
    def __init__(self, nickname, gongji, life):
        self.nickname = nickname
        self.gongji = gongji
        self.life = life
    def attack(self, obj):
        print(&#39;from Hero attack&#39;)
        obj.life -= self.gongji
class Garen(Hero):   # 使用 super方式需要继承
    camp = &#39;Demacia&#39;
    def __init__(self, nickname, gongji, life):
        super().__init__(nickname, gongji, life)
    def attack(self, obj):  # 在这里自己定义新的 attack,不再使用父类的 attack
        super(Garen, self).attack(obj)  # PY3中super可以不给参数,PY2中第一个参数必须是自己的类,self,可以使用
        父类的方法,方法需要给参数就给参数
    def fire(self):  # 在这里定义新的功能
        print(&#39;from Garen fire&#39;)
g1 = Garen(&#39;garen1&#39;, 18, 200)
g2 = Garen(&#39;garen2&#39;, 20, 100)
print(g2.life)
g1.attack(g2)
print(g2.life)
100
from Hero attack
82

Exemple 2

class A:
    def f1(self):
        print(&#39;from A&#39;)
        super().f1()    
        # 这种不需要继承也可以使用到 super,为什么,要看 C的 MRO表
class B:
    def f1(self):
        print(&#39;from B&#39;)
class C(A,B):
    pass
print(C.mro())
#[<class &#39;__main__.C&#39;>,
# <class &#39;__main__.A&#39;>,
# <class &#39;__main__.B&#39;>, #  B在A的后面,当A指定 super().f1 会找到 B的 f1
# <class &#39;object&#39;>]
c=C()
c.f1()

Combinaison :

Logiciel En plus de l'héritage, il existe un autre moyen important de réutilisation, à savoir : la composition.

Composition : L'attribut de données d'un objet est un autre objet, appelé composition.

class Equip: #武器装备类
    def fire(self):
        print(&#39;release Fire skill&#39;)
class Riven: #英雄Riven的类,一个英雄需要有装备,因而需要组合Equip类
    camp=&#39;Noxus&#39;
    def __init__(self,nickname):
        self.nickname=nickname
        self.equip=Equip() #用Equip类产生一个装备,赋值给实例的equip属性
r1=Riven(&#39;锐雯雯&#39;)
r1.equip.fire() #可以使用组合的类产生的对象所持有的方法
release Fire skill

Modes de combinaison :

La combinaison et l'héritage sont des moyens importants pour utiliser efficacement les ressources des classes existantes. Cependant, les concepts et les scénarios d’utilisation des deux sont différents.

1. Méthode d'héritage

La relation entre la classe dérivée et la classe de base est établie par héritage. C'est une relation « est », comme un cheval blanc est un cheval et un. l'humain est un animal.

Lorsqu'il existe de nombreuses fonctions similaires entre les classes, il est préférable d'extraire ces fonctions communes et d'en faire des classes de base. Par exemple, les enseignants sont des personnes et les étudiants sont des personnes. >

2. Méthode de combinaison

La relation entre les classes et les classes combinées s'établit par combinaison. Par exemple, le professeur a un anniversaire, le professeur enseigne des cours de python et de Linux. , et le professeur a des étudiants s1 et s2 , s3...

class People:
    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex
class Course:
    def __init__(self,name,period,price):
        self.name=name
        self.period=period
        self.price=price
    def tell_info(self):
        print(&#39;<%s %s %s>&#39; %(self.name,self.period,self.price))
class Teacher(People):
    def __init__(self,name,age,sex,job_title):
        People.__init__(self,name,age,sex)
        self.job_title=job_title
        self.course=[]
        self.students=[]
class Student(People):
    def __init__(self,name,age,sex):
        People.__init__(self,name,age,sex)
        self.course=[]
egon=Teacher(&#39;egon&#39;,18,&#39;male&#39;,&#39;沙河霸道金牌讲师&#39;)
s1=Student(&#39;牛榴弹&#39;,18,&#39;female&#39;)
python=Course(&#39;python&#39;,&#39;3mons&#39;,3000.0)
linux=Course(&#39;python&#39;,&#39;3mons&#39;,3000.0)
#为老师egon和学生s1添加课程
egon.course.append(python)
egon.course.append(linux)
s1.course.append(python)
#为老师egon添加学生s1
egon.students.append(s1)
#使用
for obj in egon.course:
    obj.tell_info()

5 Interface et conception normalisée

a.

L'interface extrait un groupe de fonctions communes à chaque classe. L'interface peut être considérée comme un ensemble de fonctions.

Ensuite, laissez la sous-classe implémenter les fonctions dans l'interface.

L'importance de ceci est la normalisation. Ce qu'est la normalisation, c'est que tant que les classes sont implémentées sur la même interface, alors les objets générés par toutes ces classes seront utilisés de la même manière.

L'avantage de la normalisation est :

La normalisation permet aux utilisateurs de ne pas avoir à se soucier de la classe de l'objet. Ils ont seulement besoin de savoir que ces objets ont certaines fonctions. C'est très utile. La terre réduit la difficulté d'utilisation pour les utilisateurs.

class Interface:#定义接口Interface类来模仿接口的概念,python中压根就没有interface关键字来定义一个接口。
    def read(self): #定接口函数read
        pass
    def write(self): #定义接口函数write
        pass
class Txt(Interface): #文本,具体实现read和write
    def read(self):
        print(&#39;文本数据的读取方法&#39;)
    def write(self):
        print(&#39;文本数据的读取方法&#39;)
class Sata(Interface): #磁盘,具体实现read和write
    def read(self):
        print(&#39;硬盘数据的读取方法&#39;)
    def write(self):
        print(&#39;硬盘数据的读取方法&#39;)
class Process(Interface):
    def read(self):
        print(&#39;进程数据的读取方法&#39;)
    def write(self):
        print(&#39;进程数据的读取方法&#39;)

Le code ci-dessus ressemble seulement à une interface, mais en fait il ne joue pas le rôle d'une interface. Les sous-classes n'ont pas du tout besoin d'implémenter l'interface, donc des classes abstraites sont utilisées.

6. Classe abstraite

Les sous-classes doivent hériter des méthodes des classes abstraites, sinon une erreur sera signalée.

Qu'est-ce qu'un cours abstrait ?

Comme Java, Python a également le concept de classe abstraite, mais il doit également être implémenté à l'aide de modules. La classe abstraite est une classe spéciale. Sa particularité est qu'elle ne peut être que. hérité et ne peut pas être instancié

Pourquoi avons-nous besoin de classes abstraites ?

Si une classe est extraite d'un groupe d'objets avec le même contenu, alors une classe abstraite est extraite d'un groupe de classes avec le même contenu, y compris les attributs de données et les attributs de fonction.

比如我们有香蕉的类,有苹果的类,有桃子的类,从这些类抽取相同的内容就是水果这个抽象的类,你吃水果时,要么是吃一个具体的香蕉,要么是吃一个具体的桃子。你永远无法吃到一个叫做水果的东西。

从设计角度去看,如果类是从现实对象抽象而来的,那么抽象类就是基于类抽象而来的。

从实现角度来看,抽象类与普通类的不同之处在于:抽象类中只能有抽象方法(没有实现功能),该类不能被实例化,只能被继承,且子类必须实现抽象方法。

抽象类与接口

抽象类的本质还是类,指的是一组类的相似性,包括数据属性(如all_type)和函数属性(如read、write),而接口只强调函数属性的相似性。

抽象类是一个介于类和接口直接的一个概念,同时具备类和接口的部分特性,可以用来实现归一化设计。

例1

import abc
#抽象类:本质还是类,与普通类额外的特点的是:加了装饰器的函数,子类必须实现他们
class Animal(metaclass=abc.ABCMeta):   # 抽象类是用来被子类继承的,不是用来实例化的
    tag=&#39;123123123123123&#39;
    @abc.abstractmethod   # 如果子类没有我这个函数,主动抛出异常
    def run(self):
        pass
    @abc.abstractmethod
    def speak(self):
        pass
class People(Animal):
    def run(self):   # 子类必须有抽象类里的装饰器下面的函数
        pass
    def speak(self):
        pass
peo1=People()   # 实例化出来一个人
print(peo1.tag)

例2

#_*_coding:utf-8_*_
__author__ = &#39;Linhaifeng&#39;
#一切皆文件
import abc #利用abc模块实现抽象类
class All_file(metaclass=abc.ABCMeta):
    all_type=&#39;file&#39;
    @abc.abstractmethod #定义抽象方法,无需实现功能
    def read(self):
        &#39;子类必须定义读功能&#39;
        pass
    @abc.abstractmethod #定义抽象方法,无需实现功能
    def write(self):
        &#39;子类必须定义写功能&#39;
        pass
# class Txt(All_file):
#     pass
#
# t1=Txt() #报错,子类没有定义抽象方法
class Txt(All_file): #子类继承抽象类,但是必须定义read和write方法
    def read(self):
        print(&#39;文本数据的读取方法&#39;)
    def write(self):
        print(&#39;文本数据的读取方法&#39;)
class Sata(All_file): #子类继承抽象类,但是必须定义read和write方法
    def read(self):
        print(&#39;硬盘数据的读取方法&#39;)
    def write(self):
        print(&#39;硬盘数据的读取方法&#39;)
class Process(All_file): #子类继承抽象类,但是必须定义read和write方法
    def read(self):
        print(&#39;进程数据的读取方法&#39;)
    def write(self):
        print(&#39;进程数据的读取方法&#39;)
wenbenwenjian=Txt()
yingpanwenjian=Sata()
jinchengwenjian=Process()
#这样大家都是被归一化了,也就是一切皆文件的思想
wenbenwenjian.read()
yingpanwenjian.write()
jinchengwenjian.read()
print(wenbenwenjian.all_type)
print(yingpanwenjian.all_type)
print(jinchengwenjian.all_type)

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:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer