面向对象语言的三大特征: 封装介绍
程序员文章站
2022-07-08 17:25:12
面向对象实际操作学习,什么事封装,封装的好处,怎么封装,属性化私有化...
1.什么是封装?
在程序中,封装(encapsulation)就是对具体对象的一种抽象.
简单来说: 将某些部分隐藏起来(私有化),程序的其他位置是看不到的(没有办法直接调用)
私有化:将类中的特征或者某些方法私有化,使得外部无法直接使用
2.封装的好处
- 保护隐私 — 把不想让外界知道的部分隐藏起来
- 隔离复杂度 ----- 把程序中复杂的实现 隐藏起来 —> 对外提供一个简单的接口[方法] 来使用私有化内容
- 提高代码的健壮性
- 按照实际需要添加必要的判断
3.如何封装
- 一般就是将属性私有化, 对属性提供对应的set和get方法
- 在属性名前加两个下划线就进行私有化了
为什么要进行私有化?
- 可以直接调用,也可以随意修改
- 修改后不满足实际生活需求–>bug–>不能让外界随意修改
- 简单说,就是修改前先加个条件判断下,满足条件才让你修改
class Student: def __init__(self, name, age, sex): self.name = name # self.age = age self.__age = age # 加两个下划线私有化 self.sex = sex def main(): stu = Student("诡途", 18, '男') print(stu.name) # print(stu.age) # print(stu.__age) # 也可以在外部进行随意的修改 stu.age = -10 # 不满足实际生活需求-->bug-->不能让外界随意修改 print(stu.age) if __name__ == '__main__': main()
私有化之后,无法通过属性调用,也无法修改!但是又需要调用和修改
因此,需要对外提供获取的简易接口
-
提供赋值的接口:
- 由外界来进行赋值,需要外界调用的时候传值进来,赋值的接口需要有一个形参
- 赋值方法的伪代码
def set_字段名(self, 代表字段名的形参): if 条件: self.__字段名 = ?? elif 条件: self.__字段名 = ?? else: self.__字段名 = 代表字段名的形参 #(或者是在if|elif下,根据实际需求写)
-
提供取值的接口:
- 外界只想获得这个字段的值,并不想传值,取值的接口需要有一个返回值
- 取值方法的伪代码
#伪代码 def get_字段名(self): return self.__字段名
私有化封装完整代码
class Student: def __init__(self, name, age, sex): self.name = name # self.__age = age # 因为初始化时,也是由外界赋值的, # 所以在初始化时,也需要判定数据的合理性,再进行赋值 # 因为判断数据合理性已经封装成方法了,所以直接调用赋值方法即可 self.set_age(age) self.sex = sex def set_age(self, age): # 可以按照实际生活需求加入逻辑判断 if age < 0: # 设置默认值 self.__age = 0 else: self.__age = age def get_age(self): return self.__age def main(): stu = Student("诡途", 18, '男') stu_age = stu.get_age() print(stu_age) # 调用设置的接口 stu.set_age(-10) stu_age = stu.get_age() print(stu_age) # 对象的特征值是动态赋予的 if __name__ == '__main__': main()
set和get不一定是成对出现的,按需求写
4.属性化get和set方法
- 属性化 ----> 可以在外面调用的时候 就像没有封装过一样那样调用
- 属性的调用:对象.属性名
- 方法的调用:对象.方法名()
- get和set方法属性化之后 — 调用的时候与直接调用属性的格式类似
如何进行属性化?
- 将get方法属性化的方式 ----> 系统提供的一个装饰器 @property
- 将set方法属性化方式 ----> 在get方法属性化的基础上创建出来的一个setter装饰器 —> 将set方法属性化—>格式:@get方法名.setter
【关于装饰器详解见】修改其他函数的功能的神器——python装饰器
代码样例
class Person: def __init__(self, name, age, sex): # 这些特征称之为对象的属性 self.name = name
self.age = age # self.set_sex(sex) # 属性化后,要按照属性的方式进行赋值 # self.set_sex = sex # 修改方法名 self.sex = sex # # @property # def get_sex(self): # return self.__sex @property def sex(self): return self.__sex # @get_sex.setter # def set_sex(self, sex): # if sex != "男" and sex != "女": # self.__sex = "男" # else: # self.__sex = sex @sex.setter def sex(self, sex): if sex != "男" and sex != "女": self.__sex = "男" else: self.__sex = sex # 在类的外部获取对象的属性 p = Person("诡途", 18, "男") # 获取属性的方式: 对象.属性名 print(p.name) # # 直接调用get方法 # value = p.get_sex() # print(value) # 属性化之后调用 --》只能通过属性化的方式来调用 # value = p.get_sex # 属性化之后 等价于 get_sex()() 等价于 "男"() ==》报错TypeError: 'str' object is not callable # print(value) # 属性化之后,把对属性的修改映射回,封装之前那样对属性进行修改或者获取 # 对于正常的属性进行赋值 p.name = "图图" # 对私有化属性进行赋值 # p.set_sex("女") # # 属性话后进行赋值 # p.set_sex = "女" # print(p.get_sex) p.sex = "女" print(p.sex)
因为一般的字段名 是没有set和get修饰的,所以一般给get方法和set方法命名的时候就直接命名成字段名
本文地址:https://blog.csdn.net/qq_35866846/article/details/108224333