封装、继承、多态
封装
是指在面向对象编程的思想中,对代码进行高度的封装,封装又叫包装。封装在编程中的核心作用:整体化代码,便于携带,提高数据或算法的安全性
封装的体现
# 求出1-200之间的素数
def getnum():
s = [i for i in range(1, 201)]
def fun(x):
for i in range(2, x):
if x % i == 0:
return False
else:
return True
num = filter(fun, s)
return num
print(list(getnum()))
继承
在程序中继承是指描述的是多个类之间的一个所属关系
例如一个类A里面的所有的属性和方法可以复用,这个时候可以通过继承的方式,传递到类B里面
这这里A类称之为父类(基类) B类称之为子类(派生类)
在Python中子类(派生类)会继承父类(基类),那么子类就及继承了父类中的属性和方法,简化了子类的设计问题,便于后期的维护和升级
单继承
一个类只继承了一个父类
如果子类继承了父类,子类就继承了父类的属性和方法
class A(object):
pass
class B(A)
pass
# B是子类,A是父类,B继承A
class A(object):
def __init__(self):
self.money = 1000000
self.blood = "A"
def work(self):
print("我是一名工程师")
class B(A):
pass
b = B()
print(b.money)
print(b.blood)
b.work()
#输出结果
#1000000
#A
#我是一名工程师
多继承
一个类继承了多个父类
子类继承了多个父类,则子类就会继承父类的所有的不同名的方法
class A(object):
pass
class B(object)
pass
class C(A,B):
pass
#子类C继承了A,B两个父类
class Tang(object):
def __init__(self):
self.jn1="念经"
def dyj(self):
print("我能打妖精")
class Puti(object):
def __init__(self):
self.jn2="筋斗云"
def sgz(self):
print("我能耍棍子")
class Sun(Tang,Puti):
def __init__(self):
self.jn3="七十二变"
Tang.__init__(self) # 调用同名父类的方法
Puti.__init__(self) # 调用同名父类的方法
def zhi(self):
print("还是弼马温")
sunwukong=Sun()
print(sunwukong.jn1,sunwukong.jn2,sunwukong.jn3)
sunwukong.dyj()
sunwukong.sgz()
sunwukong.zhi()
#输出结果
#念经 筋斗云 七十二变
#我能打妖精
#我能耍棍子
#还是弼马温
多层继承
class A(object):
pass
class B(A)
pass
class C(B):
pass
#B继承A,C继承B
class Puti(object):
def __init__(self):
self.model = "筋斗云"
def kongfu(self):
print("72般变化")
class SunMonken(Puti):
def __init__(self):
self.wuqi = "金箍棒"
def look(self):
print("火眼金睛")
class ChenXiang(SunMonken):
def __init__(self):
# SunMonken.__init__()
# super函数会自动查找参数中子类的“父类”按照继承链的顺序找其后一个
# super(子类名称,self).子类中的同名方法
# super(ChenXiang,self).__init__()
super().__init__()
super(SunMonken,self).__init__()
self.bao = "宝莲灯"
print(ChenXiang.__mro__)
cx = ChenXiang()
print(cx.model)
print(cx.wuqi)
print(cx.bao)
cx.kongfu()
cx.look()
#输出结果
#(<class '__main__.ChenXiang'>, <class '__main__.SunMonken'>, <class '__main__.Puti'>, <class 'object'>)
#筋斗云
#金箍棒
#宝莲灯
#72般变化
#火眼金睛
知识点
- 如果多个父类的方法名不相同
子类会全部继承 - 如果多个父类的方法名相同
子类会继承第一个父类的 - 如果子类也有父类的同名方法,那么子类就会选择自己的这个方法,
- 如果子类中也有__init__方法,那么所有的父类的属性都不会被继承
- 通过一个类创建对象,必须要执行一次init方法
找init方法的顺序要遵循类的继承链
查看一个类的继承链
类名.__mro__
子类重写父类的同名方法和属性
重写
是指在子类中重新去写父类中已经拥 有的方法,并且在子类中保持这个方法的名字不变,只有方法体发生改变,那么调用子类对象的这个方法以后都是子类中所写的
场景
- 子类继承了父类,父类不能满足子类的需求。子类重写父类的同名方法
- 但是子类还想在其类内部使用父类的同名方法
class Shi(object):
def work(self,x,y):
return x+y
class Tu(Shi):
def work(self,x,y):
return Shi.work(self,x,y)/2
pass
方式
#子类中:
父类名.父类的同名方法(self)
#使用super
#super函数是用来获取指定的子类在继承链中的后一个类给当前子类的self
super(子类名,self).父类同名方法
#一般情况下获取当前子类的直接父类的同名方法可以省略括号中的参数
super().父类同名方法
多态
不同子类的对象调用相同的父类方法,产生不同的结果
Python中多态是指一类事物有多种形态。比如动物有多种形态,人,狗,猫,等等。文件有多种形态:文本文件,可执行文件。
特点
- 多态可以增加代码的灵活度
- 以继承和重写方法为前提
- 是调用方法的技巧,不会影响类的原本设计
# 1.创建一个人类,这个类里面的属性:(姓名、年龄、身高等),要求人的年龄大于0小于300,如果用户填写小于0则默认为0
class Person(object):
def __init__(self, name,age, height):
self.name = name
self.__age = 0
self.height = height
self.set_age(age)
def set_age(self, age):
if 0 < age < 300:
self.__age = age
elif age < 0:
self.__age = 0
elif age > 300:
self.__age = 300
def get_age(self):
return self.__age
zs = Person("张三",500, 1.75)
zs.set_age(-10)
print("姓名:%s,年龄:%d岁,身高:%.2f" % (zs.name, zs.get_age(), zs.height))
#输出结果
#姓名:张三,年龄:0岁,身高:1.75