封装、继承、多态
1.封装
- 封装就是将属性隐藏,不让外界发现或使用
- 将可以允许外界使用的内容通过接口开发,让用户通过接口使用
- 隐藏属性的方法是通过 __变量名
1.1封装之隐藏属性
- 隐藏数据属性
class Teacher:
def __init__(self, name, age):
# 将名字和年纪都隐藏起来
self.__name = name
self.__age = age
# 对外提供访问老师信息的接口
def tell_info(self):
print('姓名:%s,年龄:%s' % (self.__name, self.__age))
# 对外提供设置老师信息的接口,并附加类型检查的逻辑
def set_info(self, name, age):
if not isinstance(name, str):
raise TypeError('姓名必须是字符串类型')
if not isinstance(age, int):
raise TypeError('年龄必须是整型')
self.__name = name
self.__age = age
# 实例化类得到对象
teacher = Teacher("serein", 18)
# 查看对象的信息
teacher.tell_info() # 姓名:serein,年龄:18
# 调用对象的方法修改对象的信息 , 符合要求就能修改成功
teacher.set_info('formerly', 22)
# 查看对象的信息
teacher.tell_info() # 姓名:formerly,年龄:22
- 隐藏函数属性
class ATM:
# 插卡
def __card(self):
print('插卡')
# 身份认证
def __auth(self):
print('用户认证')
# 输入金额
def __input(self):
print('输入取款金额')
# 打印小票
def __print_bill(self):
print('打印账单')
# 取钱
def __take_money(self):
print('取款')
# 取款功能
def withdraw(self):
self.__card()
self.__auth()
self.__input()
self.__print_bill()
self.__take_money()
obj = ATM()
obj.withdraw()
# 插卡
# 用户认证
# 输入取款金额
# 打印账单
# 取款
1.2 property装饰器
class Foo:
def __init__(self, val):
# 将属性隐藏
self.__NAME = val
@property
def name(self):
print(f'我在获取的时候被触发了')
return self.__NAME
@name.setter # 设置值
def name(self, value):
print(f'我再修改的时候被触发了')
# 在设定值之前进行类型检查
if not isinstance(value, str):
raise TypeError('%s must be str' % value)
# 通过类型检查后,将值value存放到真实的位置self.__NAME
self.__NAME = value
@name.deleter # 删除值
def name(self):
print(f'删除的时候调用了我')
raise PermissionError('Can not delete')
f = Foo('serein')
# print(f.name)
# 触发name.setter装饰器对应的函数name(f,'formerly')
f.name = 'formerly'
print(f.name)
# 触发name.setter对应的的函数name(f,123),抛出异常TypeError
f.name = 123
# 触发name.deleter对应的函数name(f),抛出异常PermissionError
del f.name
2.继承
- 子类可以继承父类中的方法和类变量(不是拷贝一份,父类的还是属于父类,子类可以继承而已)
- 父类也可以叫基类,子类也可以叫派生类
class Base:
def func(self):
print("Base.func")
class Son(Base):
def show(self):
print("Son.show")
s1 = Son()
s1.show() # Son.show
s1.func() # 优先在自己的类中找,自己没有才去父类。
# Base.func
2.1 属性查找顺序
class Base:
def f1(self):
print('before')
self.f2() # slef是obj对象(Foo类创建的对象) obj.f2
print('base.f1')
def f2(self):
print('base.f2')
class Foo(Base):
def f2(self):
print('foo.f2')
obj = Foo()
obj.f1() # 优先去Foo类中找f1,因为调用f1的那个对象是Foo类创建出来的。
>>> before
>>> foo.f2
>>> base.f1
b1 = Base()
b1.f1()
>>> before
>>> base.f2
>>> base.f1
查找总结
- 执行对象.方法时,优先去当前对象所关联的类中找,没有的话才去她的父类中查找。
- Python支持多继承:先继承左边、再继承右边的。
- self到底是谁?去self对应的那个类中去获取成员,没有就按照继承关系向上查找 。
2.2 隐藏属性
class Foo:
# 变形为_Foo__fa
def __f1(self):
print('Foo.f1')
def f2(self):
print('Foo.f2')
# 变形为self._Foo__fa,因而只会调用自己所在的类中的方法
# _Foo__f1
self.__f1()
#
self._Bar__f1()
class Bar(Foo):
# 变形为_Bar__f1
def __f1(self):
print('Bar.f1')
# _Bar__f1
b = Bar()
# 在父类中找到f2方法,进而调用b._Foo__f1()方法,同样是在父类中找到该方法
b.f2()
# 隐藏属性 : 隐藏给当前类,除了当前类,其他继承的子类均不能找到我隐藏的属性
标签:__,f1,封装,name,继承,self,多态,print,def
From: https://www.cnblogs.com/Formerly/p/17945571