面向对象三大特性之封装

组合

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

  • 使用组合的目的

    解决代码冗余的问题

  • 如何使用组合

    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)
原文地址:https://www.cnblogs.com/liusijun113/p/10138437.html