Three characteristics of object-oriented programming: inheritance, polymorphism, encapsulation

Three characteristics of object-oriented programming

Inheritance

what is inheritance

Inheritance is a way to create a new class, a new class can inherit one or more parent classes (python supports multiple inheritance), the parent class can also be called a base class or a super class, and the new class is called a derived class or a subclass .

The subclass will ""inherit" the properties of the parent class, thus solving the problem of code reuse (for example, the Garen and Riven classes in exercise 7 have a lot of redundant code)

Inheritance of classes in python is divided into: single inheritance and multiple inheritance

copy code
class ParentClass1: #Define parent class
    pass

class ParentClass2: #Define parent class
    pass

class SubClass1(ParentClass1): #Single inheritance, the base class is ParentClass1, and the derived class is SubClass
    pass

class SubClass2(ParentClass1,ParentClass2): #python supports multiple inheritance, separate multiple inherited classes with commas. The same parent class, multiple inherited subclasses.
    pass
copy code

View inheritance

>>> SubClass1.__bases__ #__base__ only looks at the first subclass inherited from left to right, __bases__ looks at all inherited parent classes
(<class '__main__.ParentClass1'>,)
>>> SubClass2.__bases__
(<class '__main__.ParentClass1'>, <class '__main__.ParentClass2'>)

classic and new

1. Only in python2 are new-style classes and classic classes divided into new-style classes in python3
2. In python2, classes that do not explicitly inherit the object class, as well as subclasses of this class, are all classic classes
3. In python2, explicitly declare classes that inherit object, as well as subclasses of this class, are new-style classes
3. In python3, whether object is inherited or not, object is inherited by default, that is, all classes in python3 are new-style classes
#About the difference between new-style classes and classic classes, we will discuss later

Tip: If no base class is specified, the python class will inherit the object class by default. Object is the base class of all python classes, which provides the implementation of some common methods (such as __str__).

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

Second inheritance and abstraction (first abstraction and then inheritance)

Inheritance describes the relationship between the subclass and the superclass, a what is what. To find this relationship, you must first abstract and then inherit

Abstraction is to extract similar or more similar parts.

There are two levels of abstraction: 

1. Extract the similar parts of Obama and Messi into categories; 

2. Extract the similar parts of the three classes of people, pigs, and dogs as the parent class.

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

 

Inheritance: It is based on the result of abstraction. To realize it through a programming language, it must first go through the process of abstraction before the abstract structure can be expressed through inheritance.

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

 

Three Inheritance and Reusability

  Good example of using inheritance to reuse code

 In the process of developing a program, if we define a class A, and then want to create another class B, but most of the content of class B is the same as that of class A

We can't write a class B from scratch, which uses the concept of class inheritance.

Create a new class B by inheritance, let B inherit A, and B will 'inherit' all attributes (data attributes and function attributes) of A to achieve code reuse

  View Code

Tip: Use an existing class to create a new class, which reuses a part of the existing software and most of the settings, which greatly increases the programming workload. This is often referred to as software reuse. Not only can you reuse your own classes, You can also inherit from others, such as standard libraries, to customize new data types, which greatly shortens the software development cycle and is of great significance to large-scale software development.

注意:像g1.life_value之类的属性引用,会先从实例中找life_value然后去类中找,然后再去父类中找...直到最顶级的父类。

重点!!!:再看属性查找

  View Code

四 派生

当然子类也可以添加自己新的属性或者在自己这里重新定义这些属性(不会影响到父类),需要注意的是,一旦重新定义了自己的属性且与父类重名,那么调用新增的属性时,就以自己为准了。

class Riven(Hero):
    camp='Noxus'
    def attack(self,enemy): #在自己这里定义新的attack,不再使用父类的attack,且不会影响父类
        print('from riven')
    def fly(self): #在自己这里定义新的
        print('%s is flying' %self.nickname)

在子类中,新建的重名的函数属性,在编辑函数内功能的时候,有可能需要重用父类中重名的那个函数功能,应该是用调用普通函数的方式,即:类名.func(),此时就与调用普通函数无异了,因此即便是self参数也要为其传值

copy code
class Riven(Hero):
    camp='Noxus'
    def __init__(self,nickname,aggressivity,life_value,skin):
        Hero.__init__(self,nickname,aggressivity,life_value) #调用父类功能
        self.skin=skin #新属性
    def attack(self,enemy): #在自己这里定义新的attack,不再使用父类的attack,且不会影响父类
        Hero.attack(self,enemy) #调用功能
        print('from riven')
    def fly(self): #在自己这里定义新的
        print('%s is flying' %self.nickname)

r1=Riven('锐雯雯',57,200,'比基尼')
r1.fly()
print(r1.skin)

'''
运行结果
锐雯雯 is flying
比基尼

'''
copy code

五 组合与重用性

软件重用的重要方式除了继承之外还有另外一种方式,即:组合

组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合

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

 

组合与继承都是有效地利用已有类的资源的重要方式。但是二者的概念和使用场景皆不同,

1.继承的方式

通过继承建立了派生类与基类之间的关系,它是一种'是'的关系,比如白马是马,人是动物。

当类之间有很多相同的功能,提取这些共同的功能做成基类,用继承比较好,比如老师是人,学生是人

2.组合的方式

用组合的方式建立了类与组合的类之间的关系,它是一种‘有’的关系,比如教授有生日,教授教python和linux课程,教授有学生s1、s2、s3...

  例子:继承与组合

当类之间有显著不同,并且较小的类是较大的类所需要的组件时,用组合比较好

六 接口与归一化设计

1.什么是接口

  java中的interface

PS:hi boy,给我开个查询接口。。。此时的接口指的是:自己提供给使用者来调用自己功能的方式\方法\入口

2. 为何要用接口

接口提取了一群类共同的函数,可以把接口当做一个函数的集合。

然后让子类去实现接口中的函数。

这么做的意义在于归一化,什么叫归一化,就是只要是基于同一个接口实现的类,那么所有的这些类产生的对象在使用时,从用法上来说都一样。

 

归一化的好处在于:

1. 归一化让使用者无需关心对象的类是什么,只需要的知道这些对象都具备某些功能就可以了,这极大地降低了使用者的使用难度。

2. 归一化使得高层的外部使用者可以不加区分的处理所有接口兼容的对象集合

2.1:就好象linux的泛文件概念一样,所有东西都可以当文件处理,不必关心它是内存、磁盘、网络还是屏幕(当然,对底层设计者,当然也可以区分出“字符设备”和“块设备”,然后做出针对性的设计:细致到什么程度,视需求而定)。

2.2:再比如:我们有一个汽车接口,里面定义了汽车所有的功能,然后由本田汽车的类,奥迪汽车的类,大众汽车的类,他们都实现了汽车接口,这样就好办了,大家只需要学会了怎么开汽车,那么无论是本田,还是奥迪,还是大众我们都会开了,开的时候根本无需关心我开的是哪一类车,操作手法(函数调用)都一样

3. 模仿interface

在python中根本就没有一个叫做interface的关键字,如果非要去模仿接口的概念

可以借助第三方模块:

http://pypi.python.org/pypi/zope.interface

twisted的twisted\internet\interface.py里使用zope.interface

文档https://zopeinterface.readthedocs.io/en/latest/

设计模式:https://github.com/faif/python-patterns

 

也可以使用继承: 

继承的两种用途

一:继承基类的方法,并且做出自己的改变或者扩展(代码重用):实践中,继承的这种用途意义并不很大,甚至常常是有害的。因为它使得子类与基类出现强耦合。

二:声明某个子类兼容于某基类,定义一个接口类(模仿java的Interface),接口类中定义了一些接口名(就是函数名)且并未实现接口的功能,子类继承接口类,并且实现接口中的功能

  View Code

上面的代码只是看起来像接口,其实并没有起到接口的作用,子类完全可以不用去实现接口 ,这就用到了抽象类

七 抽象类

1 什么是抽象类

    与java一样,python也有抽象类的概念但是同样需要借助模块实现,抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化

2 为什么要有抽象类

    如果说类是从一堆对象中抽取相同的内容而来的,那么抽象类是从一堆中抽取相同的内容而来的,内容包括数据属性和函数属性。

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

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

  从实现角度来看,抽象类与普通类的不同之处在于:抽象类中只能有抽象方法(没有实现功能),该类不能被实例化,只能被继承,且子类必须实现抽象方法。这一点与接口有点类似,但其实是不同的,即将揭晓答案

3. 在python中实现抽象类

  View Code

4. 抽象类与接口

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

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

八 继承实现的原理(可恶的菱形问题)

1 继承顺序

在Java和C#中子类只能继承一个父类,而Python中子类可以同时继承多个父类,如A(B,C,D)

如果继承关系为非菱形结构,则会按照先找B这一条分支,然后再找C这一条分支,最后找D这一条分支的顺序直到找到我们想要的属性

如果继承关系为菱形结构,那么属性的查找方式有两种,分别是:深度优先和广度优先

  View Code

2 继承原理(python如何实现的继承)

python到底是如何实现继承的,对于你定义的每一个类,python会计算出一个方法解析顺序(MRO)列表,这个MRO列表就是一个简单的所有基类的线性顺序列表,例如

>>> F.mro() #等同于F.__mro__
[<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]

 

为了实现继承,python会在MRO列表上从左到右开始查找基类,直到找到第一个匹配这个属性的类为止。
而这个MRO列表的构造是通过一个C3线性化算法来实现的。我们不去深究这个算法的数学原理,它实际上就是合并所有父类的MRO列表并遵循如下三条准则:
1.子类会先于父类被检查
2.多个父类会根据它们在列表中的顺序被检查
3.如果对下一个类存在两个合法的选择,选择第一个父类

九 子类中调用父类的方法

方法一:指名道姓,即父类名.父类方法()

  View Code

Method 2: super()

  View Code 

Emphasis: You can use either, but it is best not to mix 

 

Understanding part:

Even if there is no direct inheritance relationship, super will continue to look up according to mro

  View Code

The difference between naming names and super()

  View Code

When you use the super() function, Python continues searching for the next class on the MRO list. As long as each redefined method uses super() uniformly and only calls it once, the control flow will eventually traverse the entire MRO list, and each method will only be called once ( note note: use all properties called by super, They are all looking back from the current position of the MRO list. Don't look for the inheritance relationship by looking at the code. Be sure to look at the MRO list )

The method of calling the parent class in the nine subclasses

Method 1: Name the name, that is, the parent class name. Parent class method ()

  View Code

Method 2: super()

  View Code 

Emphasis: You can use either, but it is best not to mix 

 

Understanding part:

Even if there is no direct inheritance relationship, super will continue to look up according to mro

  View Code

The difference between naming names and super()

  View Code

When you use the super() function, Python continues searching for the next class on the MRO list. As long as each redefined method uses super() uniformly and only calls it once, the control flow will eventually traverse the entire MRO list, and each method will only be called once ( note note: use all properties called by super, They are all looking back from the current position of the MRO list. Don't look for the inheritance relationship by looking at the code. Be sure to look at the MRO list )

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324470409&siteId=291194637