封装
引入
- 封装是面向对象的三大特性之一
- 如果不封装的话,可以直接通过对象.属性的方式来修改属性的值,数据会非常不安全
- 封装是一种增强数据安全的方式
- 属性不能随意修改(可修改,但不要轻易修改,遵循OCP原则)
- 属性不能修改成任意值
使用
- 定义 —— 指隐藏对象中一些不希望被外界访问到的属性和方法
弱封装
- 将对象的属性名修改成外界不知道的名字
- 提供一个getter和setter方法,使外部可以访问并修改属性
- 封装增加了类定义的复杂度,但也确保了数据的安全性
- 隐藏属性名,使调用者无法随意的修改对象的属性
- 增加了getter和setter方法,很好的控制属性是否只读和修改
- 使用setter方法设置属性,可以增加数据的验证,确保数据的值是正确的
- 读取和修改属性的时候可以做一些其他处理
class Person:
def __init__(self,name):
self.hidden_name = name
def run(self):
print('%s跑步' % self.hidden_name)
p = Person('黑寡妇')
p.run()
p.name = '绿巨人'
p.run()
dir(p)
'''
[...,'hidden_name', 'name', 'run']
'''
p.name
p.hidden_name('绿巨人')
p.run()
class Person:
def __init__(self,age):
self.hidden_age = age
def get_age(self):
return self.hidden_age
def set_age(self,age):
if age >= 0:
self.hidden_age = age
p = Person(3)
p.get_age()
p.set_age(5)
p.get_age()
p.set_age(-3)
p.get_age()
强封装
- 方法 —— 对象的属性使用双下划线的方式(__属性名)
class Person:
def __init__(self,name)
self.__name = name
def get_name(self):
return self.__name
p = Person('绿巨人')
p.get_name
p.__name = '黑寡妇'
dir(p)
'''
['_Person__name',...,'get_name']
'''
p._Person__name
常用封装方法
- 方法 —— 通常在属性名前加单下划线,告知别人是封装的属性即可,因为任何封装都可以修改属性。
- 如果需要修改属性,增加getter和setter方法即可
class Person:
def __init__(self,name):
self._name = name
类的装饰器
@property
- 功能 —— 修饰方法
- 将方法转换成相同名称的属性,并且为只读属性
- 不能创建一个被property修饰的属性
class Person:
def __init__(self,name):
self._name = name
@property
def name(self):
return self._name
p = Person('哈哈')
p.name
p.name = '呵呵'
@属性名.setter
- 功能 —— 修改属性值方法
- 通常不会和property对同一个方法使用
- 可以修改属性的值
class Person:
def __init__(self,name):
self._name = name
@property
def name(self):
return self._name
@name.setter
def name(self,name):
self._name = name
p = Person('haha')
p.name
p.name = 'hehe'
p.name
@属性名.deleter
- 功能 —— 删除属性名
- deleter装饰器不能单独使用,必须配合property装饰器使用
- 将属性删除
class Person:
def __init__(self,name):
self._name = name
@property
def name(self):
return self._name
def name(self):
del self._name
p = Person('haha')
p.name
p.name()
dir(p)
'''
[...,'_name', 'name']
'''
class Person:
def __init__(self,name):
self._name = name
@property
def name(self):
return self._name
@name.deleter
def name(self):
del self._name
p = Person('haha')
p.name
del p.name
p.name
dir(p)
'''
[...,'name']
'''
继承
- 继承是面向对象的三大特性之一
- 提高了代码的复用性
- 让类与类之间产生了关系(多态的特性有此衍生)
- 使用方法
- 在定义类的时候,可以在类名后面的括号中指定当前类的父类(超类、基类)
- 在创建类的时候,如果省略了父类,则默认父类为object(object是所有类的父类)
方法的重写
- 如果子类中有和父类同名的方法,则通过子类调用方法时,会调用子类的方法而不是父类的方法。这个特点称之为方法的重写(覆盖,override)
class Person:
def __init__(self,name):
self._name = name
def run(self):
print('%s跑步' % self._name)
def sleep(self):
print('%s睡觉' % self._name)
class Doctor(Person):
def sleep(self):
print ('%s正在睡觉...' % self._name)
d = Doctor('医生')
d.run()
d.sleep()
d.speak()
Doctor.__mro__