Inheritance and derivation

Posted by AV1611 on Wed, 12 Jan 2022 20:15:24 +0100

Inheritance introduction

Inheritance is a way to create new classes. In Python, a new class can inherit one or more parent classes. The new class can be called a child class or a derived class, and the parent class can also be called a base class or a superclass

class ParentClass1: #Define parent class
    pass

class ParentClass2: #Define parent class
    pass

class SubClass1(ParentClass1): #Single inheritance
    pass

class SubClass2(ParentClass1,ParentClass2): #Multiple inheritance
    pass

 

Through the built-in properties of the class__ bases__ You can view all the parent classes that the class inherits

>>> SubClass2.__bases__
(<class '__main__.ParentClass1'>, <class '__main__.ParentClass2'>)

In Python 2, there are classic classes and new classes. Classes that do not explicitly inherit object classes and their subclasses are classic classes. Classes that explicitly inherit object and their subclasses are new classes. In Python 3, even if you do not explicitly inherit object, you will inherit this class by default, as follows

>>> ParentClass1.__bases__
(<class 'object'>,)
>>> ParentClass2.__bases__
(<class 'object'>,)

 

Therefore, in Python 3, unified classes are all new classes. We will discuss the difference between classic classes and new classes later

Tips: object Class provides implementations of some common built-in methods, such as the built-in method used to return a string when printing an object__str__

Inheritance and abstraction

To find the inheritance relationship between classes, you need to abstract first and then inherit. Abstraction is to summarize the similarities, summarize the similarities between objects to get the class, and summarize the similarities between classes to get the parent class

Subclasses can inherit / inherit all the attributes of the parent class, so inheritance can be used to solve the problem of code reuse between classes. For example, we define a Teacher class in the way we define the Student class

class Teacher:
    school='Tsinghua University'
    
    def __init__(self,name,sex,age):
        self.name=name
        self.sex=sex
        self.age=age
    
    def teach(self):
        print('%s is teaching' %self.name)
class Teacher And Student There are duplicate codes between teachers and students. Both teachers and students are human, so we can draw the following inheritance relationship to realize code reuse

class People:
    school='Tsinghua University'
    
    def __init__(self,name,sex,age):
        self.name=name
        self.sex=sex
        self.age=age
    
class Student(People):
    def choose(self):
        print('%s is choosing a course' %self.name)

class Teacher(People):
    def teach(self):
        print('%s is teaching' %self.name)

Teacher Class is not defined__init__Method, but it will be found in the parent class__init__,Therefore, it can still be instantiated normally, as follows

>>> teacher1=Teacher('lili','male',18)
>>> teacher1.school,teacher1.name,teacher1.sex,teacher1.age
('Tsinghua University', 'lili', 'male', 18)

 

Attribute lookup

With inheritance relationship, when an object looks for properties, it starts from its own__ dict__ If not, find it in the subclass, and then find it in the parent class

>>> class Foo:
...     def f1(self):
...         print('Foo.f1')
...     def f2(self):
...         print('Foo.f2')
...         self.f1()
... 
>>> class Bar(Foo):
...     def f1(self):
...         print('Foo.f1')
... 
>>> b=Bar()
>>> b.f2()
Foo.f2
Foo.f1

 

b.f2() will find f2 in the parent class Foo, and print Foo first Then proceed to self F1 (), i.e. b.f1(), will still be found in the order of object itself - > class Bar - > parent class Foo.f1 is found in class Bar, so the print result is Foo f1

If the parent class does not want the child class to override its own method, it can set the method to private by starting with a double underscore

>>> class Foo:
...     def __f1(self): # Deformation as_Foo__fa
...         print('Foo.f1') 
...     def f2(self):
...         print('Foo.f2')
...         self.__f1() # Deformation as self._Foo__fa,Therefore, it will only call the methods in its own class
... 
>>> class Bar(Foo):
...     def __f1(self): # Deformation as_Bar__f1
...         print('Foo.f1')
... 
>>> 
>>> b=Bar()
>>> b.f2() #Found in parent class f2 Method, and then call b._Foo__f1()Method is also found in the parent class
Foo.f2
Foo.f1