当你摁下电脑开机键, 你不需要考虑主板是怎么通电的、 磁盘是怎么转动的、系统的信息是怎么加载的、里面的一系列化学或者物理变化是怎么样的,你面对的就是一个开关键, 摁下它, 电脑就开起来了.
一个玩具制造厂, 制作一个机器人, 我们需要去考虑机器人的每一个细节: 手臂、腿、头、躯干等等,制作简单的玩具不要紧, 如果设计的玩具非常的复杂, 并且这工厂还有很多其他类型的玩具生产(小熊, 佩奇, 芭比公主,飞机模型等等)
上面我们使用面向过程的思想去设计, 在程序中就会让我们的代码很长, 很杂乱
于是工厂听取了小王的建议, 引进了一台制造机器人玩具的机器, 我们只需要摁下机器的开关, 它就会自动制造机器人
这个时候我们不再去关注是先制造手还是脚还是躯干这些细节, 我们面对的就只是一台机器, 这机器就是一个对象
原理 : 以前我们需要关注制作玩具的每个步骤, 现在我们将步骤都封装到一个机器里面, 留给我们的只剩一个开关, 我们只需要摁开关就可以生产玩具了, 这就是面向对象的三大特性之一 : 封装, 下面我们将详细展开介绍
在python中用双下划线开头的方式将属性隐藏起来(设置成私有的)
__xxx
都会在类定义时自动变形成:_[类名]__xxx
的形式class Eat:
__breed = "五花肉" # 变形 : "_Eat__breed"
def __init__(self):
self.__meat = "大块" # 变形 : "_Eat__meat"
def __eat(self): # 变形 : "_Eat__eat"
print(f"吃了{self.__meat}的{self.__breed}")
def eat_meat(self):
self.__eat() # 只有在类的内部才可以通过"__eat"的形式访问到
P1 = Eat()
??调用类提供的接口(方法)
P1.eat_meat() # 吃了大块的五花肉
??调用隐藏的属性/方法,报错
print(P1.breed) # 报错 "AttributeError" 没有该属性
print(P1.__breed) # 报错 "AttributeError" 没有该属性
P1.__eat() # 报错 "AttributeError" 没有该属性
??调用变形后的属性/方法(不推荐这么做)
print(P1._Eat__breed) # 五花肉
print(P1._Eat__meat) # 大块
P1._Eat__eat() # 吃了大块的五花肉
??我们来制作一个机器人,分别要考虑制作不同部件,每个方法都得调用一下
class Rebot:
def Head(self):
print("制作头")
def Hand(self):
print("制作手")
def Foot(self):
print("制作脚")
def Body(self):
print("制作躯干")
def Fit(self):
print("机器人合体")
P1 = Rebot()
??没有进行封装,我们需要进行每一个部件的调用
P1.Hand() # 制作手
P1.Head() # 制作头
P1.Foot() # 制作脚
P1.Body() # 制作躯干
P1.Fit() # 机器人合体
??当我们进行封装,提供给用户一个"Auto"接口(方法)
def Auto(self): # 提示:这个Auto方法是在类里面的,方便讲解我才放在这个位置
self.Hand()
self.Head()
self.Foot()
self.Body()
self.Fit()
??用户只需要调用"Auto"这个方法就可以一步完成上面的所有步骤
P1.Auto()
‘‘‘输出
制作手
制作头
制作脚
制作躯干
机器人合体
‘‘‘
如果这样的话, 使用者还是可以调用里面机器人的制作细节, 如果我们不想让使用者使用到那些方法, 我们就可以将细节部分给隐藏起来, 只提供一个"Auto"方法,????
__
开头,则该变量或函数为私有的_
开头的属性和方法,我们约定俗成的视其为私有, 就是上面隐藏里说到的变形后的结果, 虽然能正常调用, 但不建议这么做class Rebot:
def __Head(self): # 变形 : "_Rebot__Head"
print("制作头")
def __Hand(self): # 变形 : "_Rebot__Hand"
print("制作手")
def __Foot(self): # 变形 : "_Rebot__Foot"
print("制作脚")
def __Body(self): # 变形 : "_Rebot__Body"
print("制作躯干")
def __Fit(self): # 变形 : "_Rebot__Fit"
print("机器人合体")
def Auto(self): # 提供给使用者的接口(方法)
self.__Hand()
self.__Head()
self.__Foot()
self.__Body()
self.__Fit()
P1 = Rebot()
P1.Auto()
‘‘‘输出
制作手
制作头
制作脚
制作躯干
机器人合体
‘‘‘
# P1.__Hand() # 报错 : "AttributeError" 没有该属性
# P1.__Head() # 报错 : "AttributeError" 没有该属性
??如果特别想调用, 可以这么调用, 但非常不建议
P1._Rebot__Hand() # 制作头
P1._Rebot__Head() # 制作手
如此就实现了给使用者只看到能让他用的东西
不给用户直接使用的东西隐藏起来
class Person:
def __init__(self,name):
if not name.startswith("sb"):
self.__name = name
else:
print("名字不能以‘sb‘开头")
def print_name(self): # 打印名字的方法
print(self.__name)
def change_name(self,name): # 修改名字的方法
if not name.startswith("sb"):
self.__name = name
print("修改成功")
else:
print("名字不能以‘sb‘开头")
P1 = Person("sb_hahah") # 名字不能以‘sb‘开头
P2 = Person("shawn")
# print(P2.__name) # 报错 : "AttributeError" 没有该属性
# print(P2.name) # 报错 : "AttributeError" 没有该属性
P2.print_name() # shawn
P2.change_name("sb_kkkk") # 名字不能以‘sb‘开头
P2.change_name("xing") # 修改成功
P2.print_name() # xing
原文:https://www.cnblogs.com/songhaixing/p/14193332.html