Home  >  Article  >  Backend Development  >  One article to understand what is inheritance in Python object-oriented

One article to understand what is inheritance in Python object-oriented

爱喝马黛茶的安东尼
爱喝马黛茶的安东尼forward
2019-08-28 17:40:022949browse

One article to understand what is inheritance in Python object-oriented

1. What is inheritance?

Inheritance refers to the relationship between classes. It is a what-is relationship. One of its functions is to solve the problem of code reuse.

Inheritance is a way to create a new class. In Python, a newly created class can inherit one or more parent classes. The parent class can also be called a base class or a super class. The newly created class is called a derived class. Class or subclass, inheritance is divided into single inheritance and multiple inheritance.

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. Inheritance and abstraction

Abstraction is divided into two levels:

1. The parts that compare Obama and Messi Extract into categories;

2. Extract the more similar parts of the three categories of humans, pigs, and dogs into parent categories.

The main function of abstraction is to divide categories (which can isolate concerns and reduce complexity)

One article to understand what is inheritance in Python object-oriented

Inheritance:

is based on the result of abstraction. To implement it through a programming language, you must first go through the process of abstraction before you can express the abstract structure through inheritance.

Abstraction is just an action or a technique in the process of analysis and design, through which classes can be obtained.

One article to understand what is inheritance in Python object-oriented

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. Derived

1. Generate a subclass based on the parent class, and the generated subclass is called derived kind.

2. Methods that are not found in the parent class are found in the subclass. Such methods are called derived methods.

3. A method that exists in the parent class and also exists in the subclass is called method rewriting (that is, rewriting the method in the parent class).

Related recommendations: "Python Video Tutorial"

Example 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)

Example 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. Combination And reusability

Reusability:

Method 1: Reuse attributes without inheritance, and name the attributes of which class to use.

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)
人在塔在

Tips: Create a new class using an existing class, thus reusing part or even most of the existing software, greatly saving programming workload. This is often referred to as software reuse. Not only can you reuse your own classes, you can also inherit others, such as the standard library, to customize new data types. This greatly shortens the software development cycle, which is of great significance to large-scale software development.

Note: For attribute references like g1.life, life will be found first from the instance, then from the class, and then from the parent class... until the top-level parent class.

Method 2: By inheritance

Example 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

Example 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()

Composition:

Software In addition to inheritance, there is another important way of reuse, namely: composition.

Composition: The data attribute of one object is another object, which is called a combination.

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

Ways of combination:

Combination and inheritance are important ways to effectively utilize the resources of existing classes. However, the concepts and usage scenarios of the two are different.

1. Inheritance method

The relationship between the derived class and the base class is established through inheritance. It is a 'is' relationship, such as a white horse is a horse and a human is an animal.

When there are many similar functions between classes, it is better to extract these common functions and make them into base classes. It is better to use inheritance. For example, teachers are people and students are people.

2. Combination method

The relationship between classes and combined classes is established through combination. It is a 'have' relationship. For example, the professor has a birthday, the professor teaches python and linux courses, and the professor has students s1 and 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 and normalized design

a. Why use interface?

The interface extracts a group of common functions of the class, and the interface can be regarded as a collection of functions.

Then let the subclass implement the functions in the interface.

The significance of this is normalization. What is normalization is that as long as the classes are implemented based on the same interface, then the objects generated by all these classes will be used in the same way. .

The benefit of normalization is:

Normalization allows users to not need to care about the class of the object. They only need to know that these objects have certain functions. This is very The earth reduces the difficulty of use for users.

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;)

The above code only looks like an interface, but in fact it does not play the role of an interface. Subclasses do not need to implement the interface at all, so abstract classes are used.

6. Abstract class

Subclasses must inherit the methods of abstract classes, otherwise an error will be reported.

What is an abstract class?

Like Java, Python also has the concept of abstract class, but it also needs to be implemented with the help of modules. Abstract class is a special class. Its special feature is that it can only be inherited and cannot be instantiated

Why do we need abstract classes?

If a class is extracted from a bunch of objects with the same content, then an abstract class is extracted from a bunch of classes with the same content, including data attributes and function attributes. .

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

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

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

抽象类与接口

抽象类的本质还是类,指的是一组类的相似性,包括数据属性(如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)

The above is the detailed content of One article to understand what is inheritance in Python object-oriented. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:jianshu.com. If there is any infringement, please contact admin@php.cn delete