Python面向对象之类的封装、继承与多态

  Python面向对象中类的三大特性,即封装、继承与多态,同时也是所有语言在面向对象编程中的重要特性,下面用实际的代码部分针对每一种特性做出说明。

一、封装

  顾名思义,封装即把我们想要的内容封装到某个地方,因此在这里记录两个问题,一是如何封装、二是如何调用封装的内容。

1、封装数据

class Company:
    def __init__(self, dept, leader):
        self.dept = dept
        self.leader = leader
        
if __name__ == "__main__":    
    # 将公司名和Leader分别封装到对象obj1、obj2中self的dept和leader属性中
    obj1 = Company("A","Kevin")    
    obj2 = Company("B","Jone")

2、调用数据

  调用数据又可以分为两种方式:通过对象直接调用、通过self间接调用

class Company:
    def __init__(self, dept, leader):
        self.dept = dept
        self.leader = leader    
        
    def show(self):
        print self.dept        
        print self.leader
        
if __name__ == "__main__":
    obj1 = Company("A","Kevin")    
    obj2 = Company("B","Jone")
    
    # 通过对象直接调用封装的数据 
    print obj1.dept    
    print obj1.leader    
    
    # 通过self来间接调用,self即为对象本身
    obj1.show()
    obj2.show()

  总结封装特性:即通过类的构造方法将我们想要的内容封装到对象中,调用时通过对象直接调用、或通过self指向的类对象来间接调用。

二、继承

  顾名思义继承即为拥有了某些不属于自己的东西,Python当中类的继承同样如此,通过继承可以为我们的类扩展更多的功能,同时在代码模块化开发、升级的过程中,继承也是一种规模化、高效化的生产方式。

  不同于其他语言,Python中的类还具有多继承的特性,即可以有多个父类,下面通过代码来展示类的单继承、多继承以及继承过程中类成员方法的寻找顺序。

1、单继承

class Scale:
    def check(self):
        if self.count_person > 500:            
            print "%s is big company." %self.name        
        else:            
            print "%s is small company." %self.name
            
class Company(Scale):
    def __init__(self, name, count):
        self.name = name
        self.count_person = count
        
if __name__ == "__main__":
    my_company = Company("ABC", 800)    
    # Company类中并没有check方法,代码会向上自动检测父类中是否存在check方法,结果在Scale类中找到了
    my_company.check()

2、多继承

class Scale:
    def check(self):
        if self.count_person > 500:            
            return "%s is big company." %self.name        
        else:            
            return "%s is small company." %self.name
            
class Detail:
    def show(self, scale):
        print "%s, This company has %s persons." %(scale, self.count_person)
        
class Company(Scale, Detail):
    def __init__(self, name, count):
        self.name = name
        self.count_person = count
        
if __name__ == "__main__":
    my_company = Company("ABC", 800)
    company_scale = my_company.check()
    my_company.show(company_scale)

  上述代码中Company分别继承了父类Scale、Detail,在实例化对象my_company后,我们分别用到了父类中的check和show方法。

3、类的继承顺序

  与其说类的继承顺序,不如说是对象执行方法时,该方法在类中的查找顺序,之所以用到继承,那么一定是需要用到父类当中的某个方法,那么这个方法在类中就要遵循一定的查找顺序,简而言之可以概括为:先下后上、从左到右,下面通过代码来进行说明。

class Scale:
    def check(self):
        if self.count_person > 500:            
            print "%s is big company." %self.name        
        else:            
            print "%s is small company." %self.name
            
class Detail:
    def show(self, scale):
        print "%s, This company has %s persons." %(scale, self.count_person)
        
class Company(Scale, Detail):
    def __init__(self, name, count):
        self.name = name
        self.count_person = count    
        
    def show(self):
        print "This is display from class Company, our company has %s persons." %self.count_person
        
if __name__ == "__main__":
    my_company = Company("ABC", 800)
    my_company.check()
    my_company.show()

1) 创建实例化对象 my_company,并封装了公司名称、人数等基本内容到对象中。
2) 调用类中的check方法,此时程序发现本类中没有check方法,于是开始向上寻找,最终在Detail类中找到。
3) 调用类中的show方法,此时程序发现本类中存在show方法,直接调用。

下面来看稍微复杂些的情况,父类又继承父类,同时一个父类被多个子类同时继承,关系如下图所示。

C_5类继承了C_3和C_4类,同时C_3类、C_4类又分别继承C_1类和C_2类,C_1、C_2类又共同继承了C_0类,我们来看通过对象来调用C_5类中的special方法时,该方法在类中是按照什么顺序查找的。

class C_0:
    def special(self):
        print "I am special from C_0"
        
class C_1(C_0):
    def f1(self):
        pass
        
class C_2(C_0):
    def special(self):
        print ‘I am special from C_2‘
        
class C_3(C_1):
    def f3(self):
        pass
        
class C_4(C_2):
    def f4(self):
        pass
        
class C_5(C_3, C_4):
    def f5(self):
        pass
        
if __name__ == "__main__":
    obj = C_5()
    obj.special()

  代码最终打印了“I am special from C_0”,由此可见代码是从左边开始查找,一直找到了最顶层的C_0的special方法,但在Python3版本中,同样的情况,代码走到C_1时就会停止向上查找,而是回到C_5中继续向右查找,最终执行了C_2类中的special方法,打印了“I am special from C_2”,这是两个版本中的一点区别。

最后来看一种更为复杂的继承关系

代码如下:

class C_1:
    def show(self):
        self.detail() 
        
class C_2(C_1):
    def __init__(self):
        self.title = "This is C_2"
 
    def show(self):
        self.detail() 
        
    def detail(self):
        print ‘I am detail from C_2‘
        
class C_3(C_2):
    def __init__(self):
        self.title = "This is C_3"
        
class C_4():
    def detail(self):
        print ‘I am detail from C_4‘
        
class C_5(C_4, C_3):
    pass
    
my_data = C_5()
my_data.show()print my_data.title

这里我们讨论两个内容:
1、对象my_data中的show方法最终打印了什么内容。
2、对象my_data中的title属性中的内容是什么。

我们来分析一下整个对象实例化及其方法的调用过程
1、创建对象my_data,注意此处的C_5后面是加括号的,即创建实例化对象,此时代码按照从下到上、从左到右的顺序查找构造方法。
2、最终在C_3类中找到了__init__构造方法,并执行其中的对象属性赋值。
3、调用对象my_data中的show方法,此时代码依然按照下至上,左至右的顺序查找整个类中的show方法。
4、最终在最顶层的C_1类中找到了show方法,并执行其中的start方法。
5、代码继续从self所指的my_data对象中重新开始查找start方法。
6、从C_5中查找start方法,未找到--->C_4中,未找到--->C_3中,未找到--->C_2中,找到start方法,并执行其中的detail方法。
7、代码继续从self所指的my_data对象中重新开始查找detail方法。
8、从C_5中查找detail方法,未找到--->C_4中,找到了detail方法,并打印“I am detail from C_4”
9、由于实例化类的时候,代码自动执行了C_3中的构造方法,说以title的值为“This is C_3”

最终结果为:
I am detail from C_4
This is C_3

  总结:在类的继承中我们一直讨论从下至上,从左到右的顺序来查找对应的方法,但实际情况中,父类往往又调用了其他子类当中的方法,此时就要注意self本身的含义,self即指该类实例化对象本身,类中如果调用了self对应的方法,也就是要从对象最底层重新开始寻找对应的方法,例如上述代码中,不能误以为最终C_2中的show方法调用本类里的detail方法,要注意detail方法是要被重新查找的。理解这一点至关重要,否则我们在阅读Python项目的源码时会遇到很多困难。

三、多态

  Python当中的多态我认为是非常好理解的,顾名思义多态就是多种形态,在python中我们在对函数、或是类进行传参的时候,我们往往不会特别关心传递的参数到底是什么类型,例如它可以是字符串、可以是整型、列表、字典、甚至是任何对象,但是在其他编程语言中,参数往往需要被明确定义是什么类型,这也是Python与其他语言的区别吧。

时间: 2024-10-16 06:25:09

Python面向对象之类的封装、继承与多态的相关文章

Mysql数据库大量删除操作及谈面向对象中的封装继承和多态原理(图)

Mysql数据库大量删除操作及谈面向对象中的封装继承和多态原理(图)最近进行数据库操作,遇到一个问题,就是大量删除一个数据表中的数据后,由于设定了id是自增的,导致再插入时,默认生成的id会很大,这个时候想要再次插入新的数据,应该怎么办呢?1.明确目前最后一个id的大小select id from tags order by id DESC limit 0,1; 假设返回的是9,则设置数据表从10开始自增 2.修改这个数据表从10开始自增alter table tags auto_increme

python面向对象三大特性之继承、多态

继承 什么是继承          所谓继承指提供了同一类对象共性的处理方法,子类继承父类共性的东西. 这样有利于代码的复用性,即子类拥有父类的方法.通过继承创建的新类称为"子类"或"派生类",被继承的类称为"基类"."父类"或"超类". 继承可以想象成什么是什么的关系 python中类的继承分为:单继承和多继承 class Parent1: # 父类1 pass class Parent2: #父类2 p

Python面向对象(四)—继承、多态

继承 语法 1.代码: class 子类(父类): def __init__(self,参数列表): super().__init__(参数列表) self.自身实例变量 = 参数 设计角度: 先有子类,再有父类. 抽象化的过程:子(具体,小概念) -> 父(抽象,大概念) 编码角度: 先写父类,再写子类. 2.说明: -- 子类拥有父类的所有成员. -- 子类如果没有构造函数,将自动执行父类的,但如果有构造函数将覆盖父类的.此时必须通过super()函数调用父类的构造函数,以确保父类属性被正常

类与对象 面向对象和面向过程对比 面向对象三大特征:封装 继承 多态

 初识面向对象 面向过程: 一切以事务的发展流程为中心. 面向对象: 一切以对象为中心. 一切皆为对象. 具体的某一个事务就是对象 打比方: 大象进冰箱 步骤: 第一步, 开门, 第二步, 装大象, 第三步, 关门 面向对象:大象, 你进冰箱. 此时主语是大象. 我操纵的是大象. 此时的大象就是对象 1. 面向过程: 一切以事物的流程为核心. 核心是"过程"二字, 过程是指解决问题的步骤, 即, 先?干什么, 后干什么. 基于该思想编写程序就好比在编写一套流水线. 是一种机械 式的编程

(1) 深入理解Java面向对象三大特性 封装 继承 多态

转眼已经工作快6年了,最开始做了2年J2EE:然后整了2年的数据仓库,主要是Cognos的报表开发:现在从事4G LTE核心网的开发,用的语言任然是Java,但写代码的机会不多,基本都是看代码找BUG,偶尔做点new feature也是在比较成熟的框架上复制.粘贴.修改,大部分时间还是在理解业务,钱多.事少.离家近,当时来这家公司图的是后面2点,2年过去了,英文水平有所提升,对敏捷开放也有一定的了解,但技术方面明显退步了或者说没有进步吧,本来以前也不怎么好,因为工作上用不到,自己也没怎么学习,所

day33 序列类型,绑定方法,类方法,静态方法,封装继承和多态

Python之路,Day20 = 序列类型,绑定方法,类方法,静态方法,封装继承和多态 序列是指有序的队列,重点在"有序". 一.Python中序列的分类 Python中的序列主要以下几种类型: 3种基本序列类型(Basic Sequence Types):list.tuple.range 专门处理文本的附加序列类型(Text Sequence Types):str 专门处理二进制数据的附加序列类型(Binary Sequence Types): bytes.bytearray.mem

面向对象(一)—继承与多态

又一次深入的学习设计模式,发现了很多以前感觉不是问题的问题,这才发现原来自己不是真的理解了.通过这次的深入学习,才开始慢慢感受到OO的魅力所在. 从C#学习到设计模式,再到机房收费系统个人版和合作版,再到我们做的项目,我们真正的朝着面向对象编程了吗?我的项目中,先不说泛型.委托.集合的利用率,就是基本的继承.多态用的少之又少. 下面将为大家解说"OO引领编程"之--继承和多态 继承篇 一.简介 俗话说:龙生龙凤生凤,老鼠的儿子会打洞.可以理解为,继承就是小辈拥有父辈流传下来的东西. 在

python之7-2类的继承与多态

类的继承的意思就如同父子关系一样,这个儿子继承了父亲的一切,但是在某些地方(属性)相同的时候,儿子的属性大于老子的属性(覆盖),最底层类,总会继承最接近它的那个类的属性init 类的多态总是和继承相连的,没有继承,就没有多态一说.一个子类的实例,它即属于这个子类,也属于父类,比如:父亲A和儿子B,儿子B即属于儿子类,也属于人类,但是它不属于父亲类 多态是面向对象语言的一个基本特性,多态意味着变量并不知道引用的对象是什么,根据引用对象的不同表现不同的行为方式.在处理多态对象时,只需要关注它的接口即

面向对象三大特性:封装,继承,多态(一,封装和继承)

封装.继承和多态是面向对象程序设计的三个核心特性. 封装是面向对象技术中的一个重要概念,是一种信息隐藏技术,它体现了面向对象程序设计的思想. 继承是面向对象程序设计方法的一个重要手段,通过继承可以更有效地组织程序结构,明确类间的关系,育雏利用已有的类来完成更复杂.更深入的程序开发. 多态允许以一种统一的风格处理已存在的变量和相关的类,多态性使得向系统增加功能变的容易. 一.封装 封装的含义是:类的设计者把类设计成一个黑匣子,使用者只能看见类中定义的公共变量和公共方法,而看不见方法的具体实现细节,