Python面向对象程序设计类的封装与继承用法示例
本文实例讲述了Python面向对象程序设计类的封装与继承用法。分享给大家供大家参考,具体如下:
访问限制(封装)
1、概念
面向对象语言的三大特征:封装,继承,多态。
广义的封装:类和函数的定义本身就是封装的体现。
狭义的封装:一个类的某些属性,不希望外界直接访问,而是把这个属性私有化[只有当前类持有],然后暴露给外界一个访问的方法。
封装的本质:就是属性私有化的过程。
封装的好处:提供了数据的复用性,保证了数据的安全性。
举例:插排
2、使用
classPerson(object):
def__init__(self,name,age,height,weight,money):
self.name=name
self.__age__=age
self.weight=weight
self.__money=money
self.__height=height
defrun(self):
print(self.__money)
defeat(self):
print("eat")
#通过内部方法,去修改、获取私有属性
#通过自定义的方法实现对私有属性的赋值与取值
#set方法:setxxx
defsetMoney(self,money):
#数据的过滤
ifmoney<0:
money=0
self.__money=money
#get方法:getXXX
defgetMoney(self):
returnself.__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文件
注意:在使用继承时,尽量一个类存在于一个模块中
frompersonimportPerson
fromstudentimportStudent
fromworkerimportWorker
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)
输出:
tom18
run
110
12345
lilei20
eatapple
子类中的run方法被调用了
2
person.py文件:
#以前的写法classPerson(object):
#但是实质上,如果没有显示的写出父类,则这个类的父类默认为object
#object是所有类的父类或者超类
classPerson(object):
#构造方法
def__init__(self,name,age,money):
self.name=name
self.age=age
self.__money=money
#get/set方法
defsetMoney(self,money):
self.__money=money
defgetMoney(self):
returnself.__money
defrun(self):
print("run")
defeat(self,food):
print("eat",food)
#student.py文件 frompersonimportPerson classStudent(Person): def__init__(self,name,age,money,stuId): #调用父类中的构造方法 #方法1super(当前类,self).__init__(参数列表) #super(Student,self).__init__(name,age,money,stuId) #方法2父类名.__init__(属性列表) Person.__init__(self,name,age,money) #子类可以有一些自己独有的属性 self.stuId=stuId defsetFunc(self): print(self.__money)
#worker.py文件
frompersonimportPerson
classWorker(Person):
def__init__(self,name,age,money):
super(Worker,self).__init__(name,age,money)
#在子类中定义和一个父类中重名的函数
defrun(self):
print("子类中的run方法被调用了")
总结:
继承的特点:
a.子类对象可以直接访问父类中未私有的对象
b.子类对象可以调用父类中的方法
c.父类对象不能访问子类中特有的属性或者方法
优缺点:
优点:
1.可以简化代码,减少冗余
2.提高代码的维护性
3.提高了代码的安全性
缺点:
耦合和内聚被用来描述类与类之间的关系,耦合性越低,内聚性越高,说明代码越好。
但是,在继承关系中,耦合性相对比较高,如果修改父类,子类也会随着变化。
3、多继承
顾名思义:就是一个子类中可以有多个父类,比如一个孩子有一个爸爸一个妈妈
fromchildimportChild defmain(): c=Child(300,100,"xiaoming") print(c.money,c.faceValue) c.play() c.eat() #注意:如果多个父类中的方法名相同,默认调用的是子类括号中排前面的父类中的方法 #此时调用的是Father中func方法 if__name__=="__main__": main()
输出:
300100
play
eat
#father.py文件
classFather(object):
def__init__(self,money):
self.money=money
defplay(self):
print("play")
deffunc(self):
print("Father")
#mother.py文件
classMother(object):
def__init__(self,faceValue):
self.faceValue=faceValue
defeat(self):
print("eat")
deffunc(self):
print("Mother")
#child.py文件 fromfatherimportFather frommotherimportMother classChild(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
'''
classAnimal(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、自定义函数
重写函数的时机:当父类中函数的功能满足不了子类的需求时,就可以进行重写。
演示:
fromsmallAnimalimportSmallAnimal fromcatimportCat c=Cat() c.func()
#smallAnimal.py文件
classSmallAnimal(object):
deffunc(self):
print("wwww")
#cat.py文件
fromsmallAnimlimportSmallAnimal
classCat(SmallAnimal):
deffunc(self):
print("呵呵呵")
更多关于Python相关内容感兴趣的读者可查看本站专题:《Python面向对象程序设计入门与进阶教程》、《Python数据结构与算法教程》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》、《Python编码操作技巧总结》及《Python入门与进阶经典教程》
希望本文所述对大家Python程序设计有所帮助。