Python面向对象程序设计类的封装与继承用法示例


Posted in Python onApril 12, 2019

本文实例讲述了Python面向对象程序设计类的封装与继承用法。分享给大家供大家参考,具体如下:

访问限制(封装)

1、概念

面向对象语言的三大特征:封装, 继承, 多态。

广义的封装: 类和函数的定义本身就是封装的体现。

狭义的封装:一个类的某些属性,不希望外界直接访问,而是把这个属性私有化[只有当前类持有],然后暴露给外界一个访问的方法。

封装的本质:就是属性私有化的过程。

封装的好处:提供了数据的复用性,保证了数据的安全性。

举例:插排

2、使用

class Person(object):
 def __init__(self, name, age, height, weight, money):
  self.name = name
  self.__age__ = age
  self.weight = weight
  self.__money = money
  self.__height = height
 def run(self):
  print(self.__money)
 def eat(self):
  print("eat")
 # 通过内部方法,去修改、获取私有属性
 # 通过自定义的方法实现对私有属性的赋值与取值
 # set方法:setxxx
 def setMoney(self, money):
  # 数据的过滤
  if money < 0:
   money = 0
  self.__money = money
 # get方法:getXXX
 def getMoney(self):
  return self.__money
per = Person("hanmeimei", 20, 170, 55, 10000)
# 1.属性被私有化之后的访问
# 如果要让内部属性不被外部直接访问,在属性前加两个下划线(__),
# 在python中如果在属性前面加两个下划线,name这个属性就变成了私有属性[private]
# 私有属性的含义:在外界不能像以前那么直接访问
# print(per.__money) #无法在外界直接访问
per.run() # 内部可以访问
# 2.解决办法: 如何对私有属性取值和赋值
# 属性被私有化之后,可以通过get/set的方法进行访问
per.setMoney(10)
print(per.getMoney())
# 3.工作原理
# 不能直接访问per.__money是因为python解释器把__money变成了_Person__money
# 仍然可以使用_Person__money去访问,但是强烈不建议这么干,不同的解释器可能存在解释的变量名不一致的问题
per._Person__money = 1
print(per.getMoney())
# 4.特殊情况
# 在Python中 __xxx__ 属于特殊变量,将不再属于私有变量,可以直接访问
print(per.__age__)
# 在python中 __xxx变量,这样的实例变量外部是可以访问的,但是,按照约定的规则
# 当我们看到这样的变量时,意思虽然是"虽然我可以被访问,但是请把我视为私有变量,不要直接访问我"
print(per._Person__height)

输出:

10000
10
1
20
170

继承

1、概念

如果两个或者两个以上的类具有相同的属性和方法,我们可以抽取一个类出来,

在抽取的类中声明公共的部分

​ 被抽取出来的类 ——父类 超类 基类
​ 其他类 —— 子类 派生类
​ 他们之间的关系 ——子类继承自父类

2、单继承

简单来说,一个子类只有一个父类,被称为单继承

演示:test.py 文件

注意:在使用继承时,尽量一个类存在于一个模块中

from person import Person
from student import Student
from worker import Worker
per = Person("aa", 1, 2)
stu = Student("tom", 18, 12345, 110)
print(stu.name, stu.age)
stu.run()
print(stu.stuId)
#私有属性
#print(stu.__money)
print(stu.getMoney())#通过继承过来的共有方法访问私有属性
#stu.stuFunc()
wor = Worker("lilei", 20, 111)
print(wor.name, wor.age)
wor.eat("apple")
#子类对象调用父类同名的函数,则优先调用子类中的函数
#本质是子类中的方法覆盖了父类中同名的函数
wor.run()
print(per.getMoney())
#父类对象不能访问子类特有的属性或方法
#print(per.stuId)

输出:

tom 18
run
110
12345
lilei 20
eat apple
子类中的run方法被调用了
2

person.py文件:

#以前的写法 class Person(object):
#但是实质上,如果没有显示的写出父类,则这个类的父类默认为object
#object是所有类的父类或者超类
class Person(object):
 #构造方法
 def __init__(self, name, age, money):
  self.name = name
  self.age = age
  self.__money = money
  #get/set方法
 def setMoney(self, money):
  self.__money = money
 def getMoney(self):
  return self.__money
 def run(self):
  print("run")
 def eat(self, food):
  print("eat", food)
#student.py文件
from person import Person
class Student(Person):
 def __init__(self, name, age, money, stuId):
  #调用父类中的构造方法
  #方法1 super(当前类,self).__init__(参数列表)
  #super(Student,self).__init__(name, age, money, stuId)
  #方法2 父类名.__init__(属性列表)
  Person.__init__(self, name, age, money)
  #子类可以有一些自己独有的属性
  self.stuId = stuId
 def setFunc(self):
  print(self.__money)
#worker.py文件
from person import Person
class Worker(Person):
 def __init__(self, name, age, money):
  super(Worker,self).__init__(name, age, money)
 # 在子类中定义和一个父类中重名的函数
 def run(self):
  print("子类中的run方法被调用了")

总结:

继承的特点:

a. 子类对象可以直接访问父类中未私有的对象
b. 子类对象可以调用父类中的方法
c. 父类对象不能访问子类中特有的属性或者方法

优缺点:

优点:

1.可以简化代码,减少冗余
2.提高代码的维护性
3.提高了代码的安全性

缺点:

耦合和内聚被用来描述类与类之间的关系,耦合性越低,内聚性越高,说明代码越好。
但是,在继承关系中,耦合性相对比较高,如果修改父类,子类也会随着变化。

3、多继承

顾名思义:就是一个子类中可以有多个父类,比如一个孩子有一个爸爸一个妈妈

from child import Child
def main():
 c = Child(300, 100,"xiaoming")
 print(c.money, c.faceValue)
 c.play()
 c.eat()
 #注意:如果多个父类中的方法名相同,默认调用的是子类括号中排前面的父类中的方法
 #此时调用的是Father中func方法
if __name__ == "__main__":
 main()

输出:

300 100
play
eat

#father.py文件
class Father(object):
 def __init__(self, money):
  self.money = money
 def play(self):
  print("play")
 def func(self):
  print("Father")
#mother.py文件
class Mother(object):
 def __init__(self, faceValue):
  self.faceValue = faceValue
 def eat(self):
  print("eat")
 def func(self):
  print("Mother")
#child.py文件
from father import Father
from mother import Mother
class Child(Father, Mother):
 def __init__(self, money, faceValue,name):
  #注意:分别调用各个父类中的构造方法
  Father.__init__(self, money)
  Mother.__init__(self, faceValue)
  #子类中同样可以有自己独有的特性
  self.name = name

总结:

子类可以从多个父类中继承属性和方法
一个父类可以有多个子类
一个子类可以有多个父类

4、函数重写

4.1、系统函数

'''
重写:将函数重写一遍
__str__():在调用print打印对象时自动调用,是给用户用的,是一个描述对象的方法.
__repr__():是给机器用的,在python解释器里面直接敲对象名在回车后调用方法
注意:在没有str,且有repr时,str=repr
'''
class Animal(object):
 def __init__(self, name, age, height, weight):
  self.name = name
  self.age = age
  self.height = height
  self.weight = weight
 def __str__(self):
  return "%s-%d-%d-%d"%(self.name, self.age, self.height, self.weight)
ani = Animal("大黄", 5, 60, 25)
#print(per.name, per.age, per.height, per.weight)
#在打印ani时自动调用str函数
print(ani)
#优点或者使用时机:当一个对象的属性值很多,并且都需要打印,重写__str__方法后,简化了代码,方便查看.

输出:

大黄-5-60-25

5、自定义函数

重写函数的时机:当父类中函数的功能满足不了子类的需求时,就可以进行重写。
演示:

from smallAnimal import SmallAnimal
from cat import Cat
c = Cat()
c.func()
#smallAnimal.py文件
class SmallAnimal(object):
 def func(self):
  print("wwww")
#cat.py文件
from smallAniml import SmallAnimal
class Cat(SmallAnimal):
 def func(self):
  print("呵呵呵")

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
Python 序列化 pickle/cPickle模块使用介绍
Nov 30 Python
Python中用psycopg2模块操作PostgreSQL方法
Nov 28 Python
Python wxPython库消息对话框MessageDialog用法示例
Sep 03 Python
在python环境下运用kafka对数据进行实时传输的方法
Dec 27 Python
在Python中调用Ping命令,批量IP的方法
Jan 26 Python
Opencv-Python图像透视变换cv2.warpPerspective的示例
Apr 11 Python
python list转置和前后反转的例子
Aug 26 Python
Python3 合并二叉树的实现
Sep 30 Python
Python获取浏览器窗口句柄过程解析
Jul 25 Python
python之随机数函数的实现示例
Dec 30 Python
Pandas 稀疏数据结构的实现
Jul 25 Python
python疲劳驾驶困倦低头检测功能的实现
Apr 04 Python
详解python3 + Scrapy爬虫学习之创建项目
Apr 12 #Python
Python2和Python3的共存和切换使用
Apr 12 #Python
Python面向对象程序设计类变量与成员变量、类方法与成员方法用法分析
Apr 12 #Python
Python、 Pycharm、Django安装详细教程(图文)
Apr 12 #Python
Python面向对象程序设计构造函数和析构函数用法分析
Apr 12 #Python
Python面向对象思想与应用入门教程【类与对象】
Apr 12 #Python
Python实现的登录验证系统完整案例【基于搭建的MVC框架】
Apr 12 #Python
You might like
PHP调用Twitter的RSS的实现代码
2010/03/10 PHP
php采用ajax数据提交post与post常见方法总结
2014/11/10 PHP
9个经典的PHP代码片段分享
2014/12/18 PHP
PHP CodeIgniter框架的工作原理研究
2015/03/30 PHP
php源码之将图片转化为data/base64数据流实例详解
2016/11/27 PHP
如何通过View::first使用Laravel Blade的动态模板详解
2017/09/21 PHP
jQuery 相关控件的事件操作分解
2009/08/03 Javascript
网页编辑器ckeditor和ckfinder配置步骤分享
2012/05/24 Javascript
js事件(Event)知识整理
2012/10/11 Javascript
jQuery中setTimeout的几种使用方法小结
2013/04/07 Javascript
JQuery的ready函数与JS的onload的区别详解
2013/11/21 Javascript
javascript window.open打开新窗口后无法再次打开该窗口问题的解决方法
2014/04/12 Javascript
JavaScript中setUTCFullYear()方法的使用简介
2015/06/12 Javascript
js实现随屏幕滚动的带缓冲效果的右下角广告代码
2015/09/04 Javascript
静态页面html中跳转传值的JS处理技巧
2016/06/22 Javascript
JavaScript制作简易计算器(不用eval)
2017/02/05 Javascript
js实现类bootstrap模态框动画
2017/02/07 Javascript
JS实现简单的天数计算器完整实例
2017/04/28 Javascript
基于复选框demo(分享)
2017/09/27 Javascript
浅谈node的事件机制
2017/10/09 Javascript
Vue中保存数据到磁盘文件的方法
2018/09/06 Javascript
vue代码分割的实现(codesplit)
2018/11/13 Javascript
vscode配置vue下的es6规范自动格式化详解
2019/03/20 Javascript
layui实现鼠标移动到单元格上显示数据的方法
2019/09/11 Javascript
uniapp实现可滑动选项卡
2020/10/21 Javascript
python利用socketserver实现并发套接字功能
2018/01/26 Python
Python根据成绩分析系统浅析
2019/02/11 Python
python中的单引号双引号区别知识点总结
2019/06/23 Python
使用OpenCV-python3实现滑动条更新图像的Canny边缘检测功能
2019/12/12 Python
Windows下Anaconda安装、换源与更新的方法
2020/04/17 Python
Python能做什么
2020/06/02 Python
伊索寓言教学反思
2014/05/01 职场文书
反腐倡廉剖析材料
2014/09/30 职场文书
2015年党风廉政建设目标责任书
2015/05/08 职场文书
2019年“红色之旅”心得体会1000字(3篇)
2019/09/27 职场文书
Java实现聊天机器人完善版
2021/07/04 Java/Android