封装基础
广义上面向对象的封装:代码的保护,面向对象的思想本身就是一种封装
只让自己的对象能调用自己类中的方法
狭义上的封装-面向对象三大特性之一(私有变量,用公有的方法封装私有属性,方法叫封装)
把属性和方法都藏起来,不让你看见
类的特性
所有的私有,都是在变量左边加双下划线
所有的私有,都不能在类的外部使用
对象的私有属性
类的私有方法
类中私有的静态属性
class Person:
def __init__(self, name, password):
__key = 123 #静态私有属性
self.name = name
self.__password = password #在类的内部定义私有属性,会转换为_Person__password
def get_pwd(self): #通过公有方法get_pwd封装私有属性
return self.__password #返回__私有属性
def __set_pwd(self):#私有方法
print('set new password')
def changepwd(self):
self.__set_pwd()
#所有的私有,都是在变量左边加双下划线
#所有的私有,都不能在类的外部使用
#对象的私有属性
#类的私有方法
#类中私有的静态属性
alex = Person('alex', 'alex3714')
# print(alex.__password)#外部不可调用
print(alex.__dict__)
print(alex.get_pwd())#读取共用方法调取私有属性
使用set方法设置类变量
class Room:
def __init__(self,name, length, width):
self.__name = name
self.__length = length #私有属性
self.__width = width
def get_name(self):
return self.__name
def set_name(self,newName):#使用set方法可以规范变量的属性
if type(newName) is str and newName.isdigit() == False:#设置规范类的变量不可以是数字
self.__name = newName
else:
print('不合法的姓名')
return self.__name
def area(self):
return self.__length*self.__width #返回私有属性计算值
jin = Room('金老板', 2,1)
print(jin.area())
jin.name ='二哥'
print(jin.name)
jin.set_name('2') #传set_name数字则不修改
print(jin.get_name())
jin.set_name('东东') #传set_name字符则修改
print(jin.get_name())
>>>
2
二哥
不合法的姓名
金老板
东东
父类的私有属性可以被子类调用吗? 不可以
class Foo:
__key = '123' #变形为_Foo__Key
class Son(Foo):
print(Foo.__key) #变形为_Son__key何父类不相同
>>>
File "C:/Users/jwang2/PycharmProjects/PlayPy/Demo/S9-day25-封装.py", line 62, in Son
print(Foo.__key)
AttributeError: type object 'Foo' has no attribute '_Son__key'
总结-会用到私有概念的场景
隐藏起一个属性,不想让外部调用
保护这个属性,不想让这个属性随意改变
保护这个属性不被子类继承