引言
封装,顾名思义就是将内容封装到某个地方,以后再去调用被封装在某处的内容。所以,当我们使用封装特性时,需要将内容封装到某处,从某处调用被封装的内容。
第一步 将内容封装到某处
class Foo:
def __init__(self, name, age):
self.name = name
self.age = age
# 根据类Foo创建对象,自动执行__init__方法
obj1 = Foo("小明", 18) # 将"小明"和18自动封装到obj/self的name和age中
obj2 = Foo("张三", 25) # 将"张三"和25自动封装到obj/self的name和age中
分析:
self是一个形式参数,当执行obj1 = Foo("小明", 18) 时,self等同于obj1,对于obj2也是如此。
其实内容被封装到了对象obj1和obj2之中,每个对象都有name和age属性。
第二步 从某处调用封装的内容
调用被封装的内容时,有两种情况:
1. 通过对象直接调用
class Foo:
def __init__(self, name, age):
self.name = name
self.age = age
# 根据类Foo创建对象,自动执行__init__方法
obj1 = Foo("小明", 18) # 将"小明"和18自动封装到obj/self的name和age中
obj2 = Foo("张三", 25) # 将"张三"和25自动封装到obj/self的name和age中
print(obj1.name)
print(obj1.age)
print(obj2.name)
print(obj2.age)
结果:
小明
18
张三
25Process finished with exit code 0
2. 通过self间接调用
class Foo:
def __init__(self, name, age):
self.name = name
self.age = age
def detial(self):
print(self.name)
print(self.age)
# 根据类Foo创建对象,自动执行__init__方法
obj1 = Foo("小明", 18) # 将"小明"和18自动封装到obj/self的name和age中
obj2 = Foo("张三", 25) # 将"张三"和25自动封装到obj/self的name和age中
obj1.detial()
obj2.detial()
结果:
小明
18
张三
25Process finished with exit code 0
总结:
对于面向对象的封装来说,其实就是使用构造方法将内容封装到对象中,然后通过对象直接或者self间接获取被封装的内容。
封装及扩展
封装在于明确区分内外,使得类实现者可以修改封装内的东西而不影响外部调用者的代码;而外部使用用者只知道一个接口(函数),只要接口(函数)名、参数不变,使用者的代码永远无需改变。这就提供一个良好的合作基础——或者说,只要接口这个基础约定不变,则代码改变不足为虑。
class Room:
def __init__(self, name, owner, width, length, height):
self.name = name
self.owner = owner
self.__width = width
self.__length = length
self.__height = height
def area(self):
return self.__width * self.__length
def printInfo(self):
print("%s居住的是%s的房子,其中这个房子长为%s米,宽为%s米,高为%s米。" %
(self.name, self.owner, self.__length, self.__width, self.__height))
r1 = Room("小明", "张三", 6, 5, 4)
r1.printInfo()
print("房屋面积为%s平方米。" % r1.area())
结果:
小明居住的是张三的房子,其中这个房子长为5米,宽为6米,高为4米。
房屋面积为30平方米。Process finished with exit code 0
对外提供的接口,隐藏内部实现,此时我们想求的是体积,内部逻辑变了,只需求修该下列一行就可以很简答的实现,而且外部调用感知不到,仍然使用该方法,但是功能已经变了。如求体积:
def volume(self):
return self.__length * self.__width * self.__height
封装的作用:
1. 保护隐私,防止被继承类等其它类对其修改。
2. 隔离复杂度,模块化代码。