专栏首页诡途的python路面向对象语言的三大特征: 封装 继承 多态(一)——封装

面向对象语言的三大特征: 封装 继承 多态(一)——封装

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方法命名的时候就直接命名成字段名

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • slenium模拟登陆知乎2020

    想看登录知乎的到这里就ok了,可以撤退了,如果对selenium不太熟悉的可以直接拉到最后,参考资料里,给各位指好路了,没办法,来者是客,为了满足各位,真是老费...

    诡途
  • Message: session not created: This version of ChromeDriver only supports Chrome version 83

    一开始我还以为是 webdriver.Chrome() 原来的参数chrome_options被新的参数options替换了的原因

    诡途
  • selenium爬虫相关报错解决

    大概意思就是此参数是已经弃用的, 原来的参数chrome_options是被新的参数options替换了;

    诡途
  • Python Tkinter实战——开发音频播放器

    这部分描述,在tkinter文档中并未描述,我们需要查看tcl/Tk的 相关文档https://www.tcl.tk/man/tcl8.7/TkCmd/wm....

    arcticfox
  • Linux : E: Unable to locate package XXX

    努力在北京混出人样
  • 基于层级表达的高效网络搜索方法 | ICLR 2018

    论文: Hierarchical Representations for Efficient Architecture Search

    VincentLee
  • Python可以实现栈的结构吗

    栈(stack)又名堆栈,它是一种运算受限的线性表。在Python中可使用列表进行实现。

    砸漏
  • 汇编指令-CMP、TEQ(5)

     cmp:(compare)指令进行比较两个操作数的大小  格式: cmp oprd1,oprd2 比较oprd1和oprd2操作数,然后通过助记符来实现想要的...

    张诺谦
  • 爬了下Unsplash上的高清壁纸,总有一款适合你

    Unsplash是个高清摄影图片的网站,里面的照片非常精美,分辨率也很高,最重要的是,所有的照片都没有版权,无须向原作者申请授权,即可任意使用。

    数据森麟
  • eclipse tomcat下网页修改不生效

    大家打开eclipse JavaEE新建一个动态网页工程(File,new,project,web,Dynamic Web Project)。新建一个html静...

    似水的流年

扫码关注云+社区

领取腾讯云代金券