封装特性
概念:
总结:隐藏对象的属性和方法实现细节
封装格式:__属性或者方法名称 (是两个横杠)
封装目的:保护隐私
私有属性和私有方法只能在类的内部使用
class Girl():
def __init__(self,name,age):
self.name=name
self.__age=age#私有属性,只能在类内中访问
def show(self):
print(self.name,self.__age)
zs=Girl("张三",18)
print(zs.name)
print(zs.__age)#类外不可以访问私有属性
class Girl():
def __init__(self):
pass
def setAge(self,age):
if age<0 or age>1000:
print("来自星星的你")
self.age=0
else:
self.age=age
def getAge(self):
return self.age
zs=Girl()
zs.setAge(20)
print(zs.getAge())
zs.age=-9
print(zs.getAge())
zs.setAge(-3)
print(zs.getAge())
set和get方法
class Girl():
def __init__(self,name,age):
self.name=name
self.__age=age
pass
def setAge(self,age):
if age<0 or age>1000:
print("来自星星的你")
self.__age=18
else:
self.__age=age
def getAge(self):
return self.__age
zs=Girl("张三",20)
zs.setAge(21)
print(zs.getAge())#{'name': '张三', '_Girl__age': 21}
print(zs.__dict__)
zs.__age=99#这是添加的不属于私有属性
print(zs.__dict__)#{'name': '张三', '_Girl__age': 21, '__age': 99}
# print(zs.setAge())
# print(zs.__age)
# print(zs.__age)
# print(zs.getAge())
使用__dict__查看对象属性,并且调用私有属性和修改私有属性的值
#使用__dict__查看对象属性,并且调用私有属性和修改私有属性的值
class A():
def __init__(self,age):
self.__age=age
def setAge(self,age):
self.__age=age
def __str__(self):
return str(self._age)
a=A(1)
a.__age=21
#查看私有属性的值
print(a.__dict__)
print(a._A__age)
#修改私有属性的值
a._A__age=99
print(a.__dict__)
# print(a)
class Phone():
def __phone(self):
print("正在打电话")
def phone(self,m):
if m>=30:
self.__phone()
else:
print("请先给你的手机缴费30元,再来打电话")
x=Phone()
x.phone(38)
"""
正在打电话
"""
继承特性
继承:让类和类产生父子关系,子类可以拥有父类的静态属性和方法。
新建的类可以继承一个或多个父类
注意:python中的继承分为:单继承和多继承
概念:
父类:用于被继承的类,称之为父类,也叫做基类,或者超类
子类:继承其他类的类,称之为子类,也叫做派生类
继承作用:
提高代码的重用率
class Animal():#父类
def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex
def jiao(self):
print("叫")
def eat(self):
print("吃")
class Cat(Animal):#子类
def climb(self):
print("爬树")
class Dog(Animal):#子类
def swim(self):
print("游泳")
d=Dog("藏獒",10,"公")
c=Cat("波斯",2,"母")
#调用父类的方法
d.eat()
c.climb()
# 查看继承的父类
#python3中如果一个类没有继承任何类,默认继承object类。
print(Cat.__bases__)#(<class '__main__.Animal'>,)
print(Animal.__bases__)#(<class 'object'>,)
子类中定义了和父类中相同的方法,我们叫做方法的复写。
实例对象调用此方法的时候就会调用自己类中的方法了。
class A():
def hehe(self):
print("A:呵呵")
class B(A):
def hehe(self):
print("B:呵呵")
a=A()
b=B()
a.hehe()
b.hehe()
"""
A:呵呵
B:呵呵
"""
子类中定义了和父类中相同的方法,如果子类想调用父类相同的方法。我们可以使用super()方法。
格式:
super().方法名称()
#子类中定义了和父类中相同的方法,如果子类想调用父类相同的方法。我们可以使用super()方法。
"""
#格式:
#super().方法名称()
"""
"""
重写之后,先看自己有没有,优先用自己的
"""
class Animal():#父类
def __init__(self,name,age):#重载,重写,复写,覆盖
self.name=name
self.age=age
class Cat(Animal):#子类
def __init__(self,name,age,velocity):
self.v=velocity
super().__init__(name,age)
# Animal.__init__(self,name,age)
# def __init__(self,speed):
# self.speed=speed
def jiao(self):
print("喵喵")
class Dog(Animal):#子类
def __init__(self,name,age,height):
self.h=height
super().__init__(name,age)
def jiao(self):
print("汪汪")
d=Dog("藏獒",10,1.89)#身高
c=Cat("波斯",2,350)#要速度
#调用父类的方法
d.jiao()
c.jiao()
class A():
num=3
__num1=2
def __init__(self,x,y):
self.x=x
self.y=y
class B(A):
num=10#静态属性、类属性
def __init__(self,x,y,z):
self.z=z
super().__init__(x,y)
b=B(1,2,3)
print(b.x)
print(B.num)
print(A.num)
print(super(B,b).num)#调用父类的num
# print(B.__num1)
多继承
#多继承
class A():
def t1(self):
print("A:t1")
class B():
def t2(self):
print("B :t2")
class C(A,B):
def t3(self):
print("C:t3")
c=C()
c.t1()
c.t2()
c.t3()
"""
A:t1
B :t2
C:t3
"""
#多继承
class A():
def tx(self):
print("A:t1")
class B():
def tx(self):
print("B :t2")
class C(A,B):#A在前面,先调用A,B在前面就先调用B
def t(self):
print("C:t3")
c=C()
c.t()
c.tx()
"""
C:t3
A:t1
"""
多继承中的super本质
"""
多继承中super
不是直接找父类,而是根据调用节点的广度优先顺序执行。
"""
class A():
def func(self):
print("A开始")
print('A结束')
class B(A):
def func(self):
print("B开始")
super().func()
print("B结束")
class C(A):
def func(self):
print("C开始")
super().func()
print("C结束")
class D(B,C):
def func(self):
print("D开始")
super().func()
print("D结束")
d=D()
d.func()
#解析顺序(MRO)列表
print(D.mro())#[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
"""
D开始
B开始
C开始
A开始
A结束
C结束
B结束
D结束
"""
多态
多态:声明的形参的时候是父类对象,实际运行的时候是子类对象。
class Dog():
def jiao(self):
print("汪汪")
class Cat():
def jiao(self):
print("喵喵")
class Pig():
def jiao(self):
print("哼哼")
def honghong(a):
a.jiao()
d=Dog()
c=Cat()
p=Pig()
honghong(d)
honghong(c)
honghong(p)
"""
汪汪
喵喵
哼哼
"""
class Ali():
def pay(self,money):
print("阿里支付:",money)
class Weixin():
def pay(self,money):
print("微信支付:",money)
class Person():
def consume(self,pay,money):
pay.pay(money)
ali=Ali()
weixin=Weixin()
zs=Person()
zs.consume(ali,100)
zs.consume(weixin,200)
"""
阿里支付: 100
微信支付: 200
"""
class A():
def __init__(self):
print("A")
super().__init__()
class B():
def __init__(self):
print("B")
super().__init__()
class C(B,A):
def __init__(self):
print("C")
super().__init__()
c=C()
'''
C
B
A
'''
类方法 实例方法 静态方法
class A():
num=10
def hehe(self,name):
self.name=name
print("self",self.name)
print("我是实例方法(也叫对象方法)")
@classmethod
def haha(cls):
print("我是类方法,我的第一个参数代表的是类,例如此类是A",cls.num)
@staticmethod
def heihei():
print("我是静态方法,我跟这个类没有太多的血缘关系")
a=A()
# a.hehe(1)
# A().hehe(12)
#A.heihei()
A().hehe(a)#用类名访问对象方法,第一个参数如果传过来对象,是可以运行的
#如果考试问:用类名可以访问对象方法吗?答案:不能
a.haha()#对象(实例)访问了类方法,没出问题,因为我传进去的参数虽然是对象,但是我知道它属于哪个类
a.heihei()
# A.haha()
# A.heihei()