Python object-oriented programming (2)

PHP中文网
Release: 2017-07-09 18:13:53
Original
1249 people have browsed it

1.Inheritance and derivation

We have said above that everything in Python is an object. We extracted common characteristics and skills from objects and obtained the concept of classes. There are also common characteristics between classes. We can extract common skills and characteristics from classes with common characteristics and skills, which are called parent classes.

For example, teachers and students have names, ages, birthdays, genders, etc., and they can walk, talk, and eat. . . We can summarize a "human" class from teachers and students, called the parent class. Then teachers and students are subclasses of the "human" class. The subclass inherits the parent class and has the characteristics and methods of the parent class.

Inheritance is a relationship between what ‘is’ and something. Inheritance is a method of generating new classes. Of course, the purpose is to reduce code reuse.

The basic form of inheritance is:

<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>
Copy after login

Supports multiple inheritance in Python, a subclass can inherit multiple parent classes

We can view all inherited parent classes through the __bases__ method, which will return a 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>
Copy after login

You can see that in the People parent class, an object class is also inherited by default. This is the difference between new-style classes and classic classes:
All classes and their subclasses that inherit the object class are called new-style Classes that do not inherit the object class are called classic classes.

In Python 3, the default is the new-style class, while in Python2.X, the default is the classic class

How can inheritance reduce code? See example

<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>
Copy after login

As you can see from the above example, the Teacher class inherits the parent class People class, but Teacher has its own unique attribute level. Subclasses can also define their own unique methods, which can even overlap with the methods of the parent class. name, but the execution will be based on the definition of the subclass.

This is called derivation

2. Combination

Inheritance solves the problem of what 'is' something. Then there is another scenario where everything has something. For example, the teacher has a birthday, the student also has a birthday, and the birthday has attributes such as year, month and day. If each class is written, then It's duplicate code. But students and teachers cannot be allowed to inherit the birthday class. At this time, the combination is used. Combination is to solve the problem of what ‘has’ something. See example

<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>
Copy after login

What? Too many parameters? *Learn it, just be happy with it

<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>
Copy after login
View Code

3.Abstract classes and interfaces

Inheritance has two uses: 1. Code reuse, the subclass inherits the method of the parent class

   2. Declare that a subclass is compatible with a certain parent class and define an interface class Interface. The interface class defines some interface names (that is, function names) and does not implement the functions of the interface. The subclass inherits the interface class and implements Functions in the interface

It should be noted that there is no keyword for interface in Python. We can only imitate the functions of the interface.
For example, in Python, everything is a file, so the program is a file, the hardware is a file, and so are text documents. Files, we know what a file is, that is, it can be read and written. Programs and text documents should all have the functions of reading and writing. Let's simulate it

<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>)
Copy after login
View 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>)
Copy after login

 

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

 

The above is the detailed content of Python object-oriented programming (2). For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template