Python作为一种面向对象语言,也有着面向对象的三种特性:封装、继承、多态。

封装:

将事物相关的属性和方法封装在某一个类里面,使得在调用类创建实例时,可以不用关心类内部的实现细节。

类的本质:

1. 是将属性(全局变量),方法(函数)都封装在一个黑盒子里面;

2. 类里面的方法可以共享属性,属性的修改不会影响类的外部变量,这就是类的封装产生的优势;

3. 同时类可以被继承,子类可以拥有和父类一样的属性和方法;

4. 并且子类可以有新的属性,新的方法。

在类的内部,可以设置私有变量、私有方法:在一般变量或者方法前,加入两个下划线即可成为私有成员,但是不包括魔法方法(即前后都有双下划线的,因为魔法方法可以直接访问),私有成员一般不能外部直接访问,包括对象也不可以直接访问。

继承:

子类可以继承父类里面的属性或者方法,当然子类也可以提供自己的属性或方法,子类可以重写和覆盖父类方法或属性;python中可以多继承(此时继承的顺序很重要)。

多态:(有人说有两种多态,一种是继承多态,即子类继承自同一个父类;一种是鸭子多态,即子类继承自不同的父类)

(1)多态指的是对于同一个方法,不同对象调用时功能的表现形式不一样。

(2)python中的多态并不关注对象本身,而是关注它的功能和使用 —— 也即是有这个功能即可,并不需要共同继承一个父类(当然也可以继承自同一个父类)。

(3)在python有一个鸭子类型 (duck typing)用于实现多态,解释就是:如果一个动物走路、游泳、吃东西等都跟鸭子很像,就认为这个动物是鸭子,而不管它本身究竟是什么;

例如加法操作,对于整数类型和字符串类型来说,结果完全不一样;但是整数和字符串,却都是可以使用加法这个功能的。

总结:

多态:可以对不同类的对象使用同样的操作。

封装:对外部世界隐藏类内部的工作细节。

继承:以普通的类为基础建立专门的类对象。

示例:

1. 封装和继承,也可以用 help(class_name) 获取类的基本信息

class grandfather(object): #继承自基类 object,这个类很特别,因为所有class都会继承这个类

'''grandfather类的定义如下''' #说明文档,获取grandfather.__doc__

con_flag = 1 #普通静态字段

__con_data = '爷爷' #私有静态变量只能在类内使用

def __init__(self,name,age,id_): #初始化方法,实例化的时候自动调用

self.name =name

self.age=age

self.__id =id_print('grandfather类初始化完成')def __get_age(self): #私有函数只能在类内使用

returnself.agedefshow_age(self):print(self.age)print('grandfather年龄显示完毕')

这个类 grandfather封装了一个静态变量、一个私有化变量、三个方法(一个魔法方法__init__,一个私有化方法__get_age,一个一般方法show_age)。

实例化对象时,会自动执行魔法方法__init__,当然注意:如果该方法有其他参数(除self外),那么实例化对象时必须要传入参数才行。

上述类中,类定义的(object)表示继承;__init__方法实例化时自动执行,且第一个参数self表示创建的类实例本身,不需要传入这个参数,而是使用时会自动填充当前对象;在__init__方法中,可以把很多属性绑定到self中,因为它指向的就是实例本身。

注意:这里的名称也不一定要用self,可以换成其他的,只要是第一个参数就行,只不过默认用这个self代表自身比较直观。

if __name__ == '__main__':grandfather1= grandfather('g1',70,'002') #实例化对象

grandfather1.show_age() #调用方法

2. 继承:子类继承父类的属性和方法,如果子类中有同名的属性或者方法,则子类会覆盖父类的属性或方法;如果子类中找不到某属性或方法,会去父类中查找;多继承时,有查找顺序(python的C3算法计算的顺序,通过类名.mro()或者 类型.__mro__可获取顺序)。

示例:

classgrandfather(object):'''grandfather类的定义如下'''con_flag= 1 #普通静态字段

__con_data = '爷爷' #私有静态变量只能在类内使用

def __init__(self,name,age,id_):

self.name=name

self.age=age

self.__id =id_print('grandfather类初始化完成')def __get_age(self): #私有函数只能在类内使用

returnself.agedefshow_age(self):print(self.age)print('grandfather年龄显示完毕')class father(grandfather): #继承自grandfather类

'''father类的定义如下'''con_flag= 2 #普通静态字段

__con_data = '爸爸' #私有静态变量只能在类内使用

def __init__(self,name,age,id_):

self.name=name

self.age=age

self.__id =id_print('father类初始化完成')defshow_age(self):print(self.age)print('father年龄显示完毕')class son(father): #继承自father类

'''son类的定义如下'''con_flag= 3 #普通静态字段

__con_data = '儿子' #私有静态变量只能在类内使用

def __init__(self,name,age,id_):

self.name=name

self.age=age

self.__id =id_print('son类初始化完成')def set_age(self, age): #用于间接修改私有变量

self.age =agedefshow_age(self):print(self.age)print('私有静态变量:',self.con_flag)print('私有静态变量:',self.__con_data) #类内使用私有变量

print('son年龄显示完毕')

使用时:

if __name__ == '__main__':

son1= son('Tom',12,'001') #实例化,如果子类有__init__方法,就会使用子类的;否则使用父类的

son1.show_age()print(son1.con_flag) #对象直接访问非私有变量

print(son1._son__con_data) #对假私有变量进行访问

son1.set_age('13')

son1.show_age()

son1.con_flag= 100 #可该方式可以直接修改

print(son1.con_flag)

son1._son__con_data= 1000 #可该方式可以直接修改私有变量

print(son1._son__con_data)

son1.show_age()#print(son1.__con_data) #AttributeError: 'son' object has no attribute '__con_data',因为是私有变量,不能直接用

首先,这里的子类中方法重写了父类的方法,相当于实例化时使用时直接用的是子类的__init__方法。

其次,前面说了,私有成员不能直接访问,但是可以间接访问,(严格的说python的私有属于假私有),有以下两种方式:

(1)通过在类中设置访问私有成员的非私有函数,例如son类中的set_age 函数;

(2)通过对象来访问,方式是:对象名._类名__私有成员名,例如这里的:son1._son__con_data。

而且,如果子类中没有__init__方法,但父类中有,那么实例化子类时,也需要传参数,因为子类会继承父类的属性和方法。

classdog(father):'''dog类的定义如下'''con_flag= 5 #普通静态字段

__con_data = '狗狗' #私有静态变量只能在类内使用

defshow_age(self):print(self.age)print('dog年龄显示完毕')

调用:

dog1 = dog('dog1',5,'005') #使用了父类的初始化函数__init__(),如果父类没有,会继续向上回溯查找,直到找到__init__方法或者都没有该方法#dog2 = dog() #报错,因为父类中存在__init__方法

print(dog1.name)

dog1.show_age()

如果,子类和父类及以上均没有__init__方法,那么实例化子类时不需要传参数。

class cat(object): #cat(dog)

'''cat类的定义如下'''con_flag= 6 #普通静态字段

__con_data = '猫' #私有静态变量只能在类内使用

age = 10

defshow_age(self):print(self.age)print('cat年龄显示完毕')classpig(cat):'''pig类的定义如下'''con_flag= 7 #普通静态字段

__con_data = '猪' #私有静态变量只能在类内使用

age= 5 #覆盖父类属性,因为是先查找子类,再依次向上查找

defshow_age(self):print(self.age)print('pig年龄显示完毕')

使用时:

cat2 =cat()

cat2.show_age()

pig1=pig()

pig1.show_age()

3. 多态:两种多态形式 —— 继承多态和鸭子多态

classgrandfather(object):'''grandfather类的定义如下'''con_flag= 1 #普通静态字段

__con_data = '爷爷' #私有静态变量只能在类内使用

def __init__(self,name,age,id_):

self.name=name

self.age=age

self.__id =id_print('grandfather类初始化完成')def __get_age(self): #私有函数只能在类内使用

returnself.agedefshow_age(self):print(self.age)print('grandfather年龄显示完毕')classfather(grandfather):'''father类的定义如下'''con_flag= 2 #普通静态字段

__con_data = '爸爸' #私有静态变量只能在类内使用

def __init__(self,name,age,id_):

self.name=name

self.age=age

self.__id =id_print('father类初始化完成')defshow_age(self):print(self.age)print('father年龄显示完毕')classdaughter(father):'''daughter类的定义如下'''con_flag= 4 #普通静态字段

__con_data = '女儿' #私有静态变量只能在类内使用

def __init__(self,name,age,id_):

self.name=name

self.age=age

self.__id =id_print('daughter类初始化完成')defshow_age(self):print(self.age)print('daughter年龄显示完毕')def show_func(obj): #类似接口一样,不判断对象的类型,直接使用函数

obj.show_age()if __name__ == '__main__':print('--- 多态 ---')

grandfather1= grandfather('g1',70,'002')

father1= father('f1',34,'003')

daughter1= daughter('d1',14,'004')

show_func(grandfather1)

show_func(father1)

show_func(daughter1)

很明显,这三个类继承的都不是一样的父类,但是却存在相同的方法(都重写了父类的方法),所以可以直接像接口一样,通过对象直接调用 —— 鸭子多态。

如果子类时继承自相同的父类呢?不重写方法的话:

classson(father):'''son类的定义如下'''con_flag= 3 #普通静态字段

__con_data = '儿子' #私有静态变量只能在类内使用

def __init__(self,name,age,id_):

self.name=name

self.age=age

self.__id =id_print('son类初始化完成')classdaughter(father):'''daughter类的定义如下'''con_flag= 4 #普通静态字段

__con_data = '女儿' #私有静态变量只能在类内使用

def __init__(self,name,age,id_):

self.name=name

self.age=age

self.__id =id_print('daughter类初始化完成')

使用时:

print('---- 继承多态 ----')

son2= son('Jack',12,'001')

daughter2= daughter('Nancy',14,'004')

son2.show_age()

daughter2.show_age()

可见这两个实例化对象都调用了父类的相同方法,但是结果是不一致的 —— 继承多态。

总结:

私有成员在类外可以通过间接方式访问。

类中的对象参数不一定要是self,可以是其他的。

python的多重继承下次探讨。

#

参考:

python封装继承多态_Python:封装、继承、多态、私有成员相关推荐

  1. 设计复数类 Complex继承于数字类 Number,私有成员变量包括 double类型的实部rea(父类 Number中已定义)和虚部imag,公有成员方法包括两个构造方法(一个不带参数的和一个带两

    ​ 设计复数类 Complex继承于数字类 Number,私有成员变量包括 double类型的实部rea(父类 Number中已定义)和虚部imag,公有成员方法包括两个构造方法(一个不带参数的和一个 ...

  2. python 多态_Python中的多态

    面向对象的语言有四个特性,抽象.封装.继承和多态.在之前的文章中,给小伙伴们已经讲解了前三个.为什么要把多态放在最后一个讲呢?因为前面的三个特性是多态的基础,了解了前三个,了解多态就很容易啦~ 那么, ...

  3. python封装的方法_Python封装原理与实现方法详解

    本文实例讲述了Python封装原理与实现方法.分享给大家供大家参考,具体如下: [封装] 隐藏对象的属性和实现细节,仅对外提供公共访问方式. [好处] 1. 将变化隔离: 2. 便于使用: 3. 提高 ...

  4. python的继承用法_python之继承中组合用法与菱形继承关系查找法

    1.什么是组合 组合就是一个类的对象具备某一属性,该属性的值是指向另外外一个类的对象 2.为什么用组合 组合也是用来解决类与类之间代码冗余问题 3.用法 class Course:           ...

  5. 微课|中学生可以这样学Python(7.3.1节):私有成员与公有成员

    适用教材: 董付国,应根球.<中学生可以这样学Python>.清华大学出版社,2017. 第7章  面向对象程序设计 7.3.1  私有成员与公有成员 京东购买链接:https://ite ...

  6. python的继承用法_python中继承有什么用法?python继承的用法详解

    本篇文章给大家带来的内容是关于python中继承有什么用法?python继承的用法详解,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 面向对象三大特征 1.封装:根据职责将属性和方法 ...

  7. python面向对象三大特性_Python面向对象之多态原理与用法案例分析

    本文实例讲述了Python面向对象之多态原理与用法.分享给大家供大家参考,具体如下: 目标 多态 面向对象三大特性 封装 根据 职责 将 属性 和 方法 封装 到一个抽象的 类 中 定义类的准则 继承 ...

  8. python什么是多态_Python中的多态是什么

    多态的概念其实不难理解,它是指对不同类型的变量进行相同的操作,它会根据对象(或类)类型的不同而表现出不同的行为. 事实上,我们经常用到多态的性质,比如:>>> 1   2 3 > ...

  9. python的继承模式_Python之继承--增加新功能,不更改以前的代码

    在实际工作中,设计模式的时候,要增加新功能,不要更改以前的代码,这是封装和继承的高度总结. isinstance('对象',"类") 返回Ture or False issubcl ...

  10. python类继承实例_python类继承与子类实例初始化用法分析

    这篇文章主要介绍了python类继承与子类实例初始化用法,实例分析了Python类的使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下 [ 先贴参考书籍原文(中文英文对照)] __init__方法介 ...

最新文章

  1. python 中shape 1,n 与1的区别
  2. 用Transformer定义所有AI模型!特斯拉AI总监Karpathy发推感叹AI融合趋势
  3. 1000内同时被3,5,7整除的数
  4. 为Openshift + MongoDb应用程序编写验收测试
  5. TiDB集群大规模删除实践
  6. 2021年浙江省高考成绩查询哪里快,2021年浙江高考成绩排名及成绩公布时间什么时候出来...
  7. python getopt_Python getopt
  8. 【转】VC2008 配置OpenGL环境
  9. matlab动态更新数组值,Matlab动态数组实现
  10. py笔记.字典的使用
  11. 脑机接口新进展!只凭意念,操纵机器移动、拿取物体成为现实
  12. FUNCTION count does not exist
  13. Unity 自学成长路线总结
  14. QT软件开发之入门基础-搭建开发环境
  15. matplotlib动画演示:细胞自动机-探索生命起源
  16. python的栈在哪个库_Python算法实战系列之栈
  17. PLSQL连接ORACLE报错ORA-12541:TNS:无监听程序
  18. Ceph入门到精通-rados bench性能基准测试
  19. SOLIDWORKS草图编辑——草绘圆命令
  20. 对话微软CEO纳德拉:数据就是当今的货币

热门文章

  1. 张文中复出,物美首次披露新零售转型内幕
  2. 《例说51单片机(C语言版)(第3版)》——1-2 8051基础知识
  3. PostgreSQL 变成充气娃娃,怪谁?
  4. 计算机毕业设计Java牙科诊所管理系统(源码+系统+mysql数据库+Lw文档)
  5. 如何彻底卸载有道词典
  6. 9102年了,还不知道Android为什么卡?
  7. Latex编辑出现Misplaced alignment tab character . 解决办法
  8. c ringbuffer 源码_【源码】RingBuffer(一)——生产者
  9. 我的3D之路-----非教科书式3D计算机图形学零起点全攻略
  10. java定时数据同步_java 定时同步数据的任务优化