• 面向对象三大特性之封装


    组合

    • 什么是组合:一个对象的属性来自于另一个类的对象,称之为组合,那这个对象就获得了另一个对象的属性和功能

    • 使用组合的目的

      解决代码冗余的问题

    • 如何使用组合

      class Phone:
          def __init__(self,phonenumber,operator,address):
              self.phonenumber = phonenumber
              self.operator = operator
              self.address = address
      ​
          def call(self):
              print("%s 正在拨号" % self.phonenumber)
      ​
      ​
      class Person:
          def __init__(self,name,sex,age):
              self.name = name
              self.sex = sex
              self.age = age
      ​
      ​
      class Student(Person):
          def __init__(self,name,sex,age,number):
              super().__init__(name, sex, age)
              self.number = number
      ​
          def show_info(self):
              print(self.__dict__)
      ​
          def select_course(self):
              print("%s 正在选课...." % self.name)
      ​
      class Teacher(Person):
          def __init__(self,name,sex,age,salary,level):
              super().__init__(name,sex,age)
              self.salary = salary
              self.level = level
          def set_score(self):
              print("%s 正在为学生打分..." % self.name)
      ​
      ​
      stu = Student("乔峰","",38,"007")
      ​
      # 学生买了一台手机 所以增加一个手机属性
      p1 = Phone("1999999999","中国小米移动","上海浦东")
      ​
      stu.phone = p1  # 组合代码
      # 学生要打电话
      stu.phone.call()
    • 组合与继承的区别:

      1. 继承是一种方法,是类与类之间的关系,是同类只间的的传递

      2. 组合是对象之间的关系

    封装

    • 封装:在程序中,封装指的是将内容隐藏起来,在面向对象种隐藏的是属性和方法

      注意:封装不是单纯的隐藏,只是隐藏内部细节,对外提供使用接口

    • 封装的目的:

      1. 提高安全性:

        1. 对于封装属性而言,是通过给访问和修改增加额外的验证来实现

        2. 对于封装方法而言,提高安全性,和隔离复杂度(将复杂的内容隔离到内部,外部只留下简单的接口,对于使用者,难度降低)

      2. 封装是为了明确区分内部和外部

      3. 对于封装方法而言,可以隔离复杂度

    • 如何封装:

      • 属性的封装:

        在属性或者方法名称前添加两个下划线"__" ,就可以将其设置成私有的

      补充:在python中权限只有两种,公开(谁都能访问)和私有的(只有自己能访问的)

      # 封装属性
      class Student:
          def __init__(self, name, age, sex, id_card):
              self.name = name
              self.age = age
              self.sex = sex
              self.__id_card = id_card  # 在属性前加__,对其封装
      def say_hi(self):
              print('hello i am %s age is :%s sex is %s' %
                    (self.name, self.age, self.sex))
      ​
          def test(self):
              print(self.__id_card)
      ​
          # 訪問封裝屬性
          def get_id_card(self):
              return self.__id_card
          
          # 加密访问
          def get_id(self, pwd):
              if pwd == 123:
                  return self.__id_card
              else:
                  return '密码错误'# 修改封裝屬性
          def set_id(self, pwd, new_id):
              if pwd == 1234:
                  self.__id_card = new_id
      ​
      ​
      stu = Student('jason', 23, 'male', '1234567')
      ​
      print(stu.get_id(123))  # 修改封装前
      ​
      stu.set_id(1234, 'xxxxxx')  # 执行修改
      print(stu.get_id_card())  # 执行修改后结果
      # 运行结果
      1234567
      xxxxxx
      ​
      ​
      # 对方法进行封装
      class Atm:
          def __insert_card(self):
              print('插入银行卡')
      ​
          def __input_pwd(self):
              print('输入密码')
      ​
          def __selectmoney(self):
              print('选择金额')
      ​
          def withdraw(self):
              self.__insert_card()
              self.__input_pwd()
              self.__selectmoney()
              print('取款成功')
      ​
      ​
      atm = Atm()
      atm.withdraw()
    • 封装的特点:

      • 在类的内部可以访问得到,类的外部无法访问

    • 封装的实现原理

      本质上python并没有强行限制你的访问,而是通过方法的转换进行封装

      1. 通过__ dict__ 可以发现 私有的属性名称 前自动加上了__类名 python就是这样的转换方式实现的封装.

      2. 只有在类的内部的双下划线才会被自动转换,并且这个转换过程只执行一次,在类定义完成后,再添加的双下划线开头的名称是不会自动装换的.

      3. 父类中私有的方法,子类中无法使用

    • property装饰器

      • property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值

      • 为什么要用property

        将一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的name是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则

      • 什么时候用property

        当一个属性不是固定需要计算得来时,调用时还是要以属性的调用方式,这个时候我们就要用property为其装饰.

      • setter和deleter,修改和删除被property伪装的函数属性
    class People:
        def __init__(self, name, weight, height):
            self.name = name
            self.weight = weight
            self.height = height
    
        @property  # 添加装饰器
        def bmi(self):
            return self.weight / (self.height**2)
    
    
    p1 = People('Jason', 78, 1.83)
    print(p1.bmi)  # 函数伪装后的属性的访问方法访问,不可赋值和删除
    
    # 如果非要修改赋值,那么就要用到setter装饰器
    # 如果非要删除,就要用到delter装饰
    
    class Student:
        def __init__(self,name,sex,idCard):
            self.name = name
            self.sex = sex
            self.__idCard = idCard
    
        def get_idCard(self):
            return self.__idCard
    
        def set_idCard(self, new_id):
            self.__idCard = new_id
    
        @property # 需要掌握
        def idCard(self):
            return self.__idCard
    
    
        @idCard.setter  # 更改伪装属性
        def idCard(self,new_id):
            self.__idCard = new_id
    
        @idCard.deleter # 删除伪装属性
        def idCard(self):
            print("身份证属性被删除了.....")
            del self.__idCard
    
    
    stu = Student("尔康","","323254554554")
    
    
    print(stu.get_idCard()) # 使用装饰器前
    print(stu.name) # 普通属性的访问
    
    print(stu.idCard) # 使用装饰器后
    
    stu.idCard = "aaaaaaa" # 使用装饰器后的修改操作
    
    print(stu.idCard)
  • 相关阅读:
    20145222黄亚奇《Java程序设计》第4周学习总结
    20145222黄亚奇《Java程序设计》第3周学习总结
    20145222黄亚奇《Java程序设计》第2周学习总结
    CodeForces
    2020 Multi-University Training Contest 3 1008 Triangle Collision
    Educational Codeforces Round 92 (Rated for Div. 2) E. Calendar Ambiguity
    2020 Multi-University Training Contest 3 1006 X Number
    2020 Multi-University Training Contest 3 1004 Tokitsukaze and Multiple
    2020 Multi-University Training Contest 2 1007 In Search of Gold
    2020 Multi-University Training Contest 1 1009 Leading Robots
  • 原文地址:https://www.cnblogs.com/liusijun113/p/10138437.html
Copyright © 2020-2023  润新知