zoukankan      html  css  js  c++  java
  • python面向对象之封装

    1. 封装(实际封装python中的封装只是一个约定)

    第一层面的封装:类就好像一个袋子,这就是一种封装

    第一阶段:

    # 如果我们要定义学生jack如何定义?
    name = 'jack'
    age = 17
    sex = '男'
    
    这三个变量可以用来形容jack这个人(当然你也可以使用字典,列表去描述).但是我们用三个变量去形容这个人,有什么弊端?
    	弊端:太零散,如果学生太多,需要有很多变量去描述
    为了解决这个问题,因此才有了类。
    

    第二阶段:

    class Student(object):
    
        def __init__(self,name,age,sex):
            self.name = name
            self.age = age
            self.sex = sex
    
    one = Student('jack',17,'男') # 这里的one就相当于一个学生jack,所有的属性都封装到了one变量中。这里的Student类,相当于一个模板。只要给定它name,age,sex,它就能创建出一个学生对象。
    two = Student('aaa',16,'男')
    three = Student('bbb',15,'女')
    four = Student('ccc',14,'男')
    five = Student('ddd',13,'女')
    print(f'姓名:{one.name}   年龄:{one.age}    性别:{one.sex}')
    
    姓名:jack   年龄:17    性别:男
    

    到这里,不知道你是否已经体会到使用类封装的便利没!

    第二层面的封装:类中定义私有的,只有类内部使用,外部无法访问(比如_(杠) __(杠杠) )

    第一阶段:

    class Student(object):
    
        def __init__(self,name,age,sex):
            self.name = name
            self.age = age
            self.sex = sex
    
    
    one = Student('plf',18,'男')
    one.name = 'who'
    one.age = -28
    one.sex = '人妖'
    print(f'姓名:{one.name}   年龄:{one.age}    性别:{one.sex}')
    
    姓名:who   年龄:-28    性别:人妖
    

    问题:我们在外部能随意访问到对象one的属性,并且随意修改,这样数据是不安全的,因为我们需要将属性隐藏起来。那我们应该如何去做了?

    第二阶段:

    class Student(object):
    
        def __init__(self,name,age,sex):
            self.__name = name
            self.__age = age
            self.__sex = sex
    
    one = Student('plf',18,'男')
    
    print(one._Student__name)
    print(one._Student__age)
    print(one._Student__sex)
    
    one._Student__age = 20	
    print(one._Student__age)
    
    
    rint(one.__name)       # 报错,无该属性
    print(one.name)         # 报错,无该属性
    
    plf
    18
    男
    20
    

    此时发现,我们虽然不能使用one.name或者one.__name访问到该属性。但是我们可使用one._Student__age访问到对象的age属性并且能修改。说明python在设置私有属性的时候,只是把属性的名字换成了其他的名字。

    总结:

    ​ 类中以_或者__的属性,都是私有属性,禁止外部调用。虽然我们可以通过特殊的手段获取到,并且赋值,但是最好不要这么做(约定俗成)

    问题:现在我将name,age,sex设置为私有属性,但是我又想让他们通过我指定的接口去访问或者修改我的属性,应该如何实现了?

    第三阶段:

    Student(object):
    
        def __init__(self,name,age,sex):
            self.__name = name
            self.__age = age
            self.__sex = sex
    
        def get_name(self):
            return self.__name
    
    
        def set_name(self,name):
            if len(name) > 1 :
                self.__name = name
            else:
                print("name的长度必须要大于1个长度")
    
        def get_age(self):
            return self.__age
    
        def set_age(self, age):
            if age > 0 and age < 150:
                self.__age = age
            else:
                print("输入的年龄必须要大于0,小于150岁")
    
    one = Student('plf',18,'男')
    
    one.set_name('a')       # 通过自己设置接口,可以有效规避脏数据
    print(one.get_name())       # 通过接口获取数据
    
    
    one.set_age(-9)         # 通过自己设置接口,可以有效规避脏数据
    print(one.get_age())    # 通过接口获取数据
    
    name的长度必须要大于1个长度
    plf
    输入的年龄必须要大于0,小于150岁
    18
    

    这样我们就自定义了自己属性的接口,它的好处在于:规避脏数据

    问题:使用接口设置获取数据 和 使用点方法(one.name = 18 或者print(one.name))设置数据相比, 点方法使用更方便,我们有什么方法达到 既能使用点方法,同时又能让点方法直接调用到我们的接口了? 其他python已经帮我们实现了,让我们一起看一下吧!

    第四阶段:

    class Student(object):
    
        def __init__(self,name,age,sex):
            self.__name = name
            self.__age = age
            self.__sex = sex
    
        @property
        def name(self):
            return self.__name
    
        @name.setter
        def name(self,name):
            if len(name) > 1 :
                self.__name = name
            else:
                print("name的长度必须要大于1个长度")
    
        @property
        def age(self):
            return self.__age
    
        @age.setter
        def age(self, age):
            if age > 0 and age < 150:
                self.__age = age
            else:
                print("输入的年龄必须要大于0,小于150岁")
    
    
    one = Student('plf',18,'男')
    
    one.name = '张三'
    print(one.name)
    
    one.age = 170
    print(one.age)
    
    张三
    输入的年龄必须要大于0,小于150岁
    18
    

    总结:

    1. 使用 @property 装饰器时,接口名不必与属性名相同.
    2. 凡是赋值语句,就会触发set方法。获取属性值,会触发get方法
  • 相关阅读:
    vuex之store拆分即多模块状态管理
    vue项目中使用vueX
    vue中父子组件的参数传递和应用
    VUE中使用vue-awesome-swiper
    VUE真实项目中常用的生命周期和参数
    VUE生命周期
    vue+mockjs 模拟数据,请求回调的应用
    Vue项目搭建与部署还有调试插件Vue.js devtools
    tableTD中添加对角斜线
    前端面试题及答案,理论知识
  • 原文地址:https://www.cnblogs.com/plf-Jack/p/11051933.html
Copyright © 2011-2022 走看看