面向对象的三大特征

面向对象有自己的三大特征,分别是:

  1. 封装:还原了对象的数据的隐私性,私有化操作
  2. 继承:重复使用已有的资源完成新功能的扩展,复用性操作
  3. 多态:在不同的场景下,每个对象体现角色的不同的状态,多样性操作

封装

什么是封装

封装,是面向对象的第一个特征,体现了数据的私有化操作,将对象的敏感数据隐藏在对象的内部,不让外界直接访问。提供了外界访问敏感数据的方法,在方法中添加了访问限制条件,让外界通过方法来访问自己的隐私数据。

  1. 所有属性私有化
  2. 所有属性提供访问方法
  3. [对应方法中添加限制条件]

怎么实现封装

没有封装,直接使用

代码的开发效率是最高的,但是数据的保护性是最差的!
如果开发的软件中,对于数据的安全性要求较低的话,可以直接使用这样的方式进行开发!

class Person:
    def __init__(self, name, age):
        """属性没有封装"""
        self.name = name
        self.age = age

damu = Person("大牧")
print(damu.name)

约定封装,项目规范

代码开发过程中,约定以一个下划线卡头的属性或者方法,是当前类型中受到保护的属性或者方法,类的外部不要去直接调用执行。(传统项目中经常遇到)

class Person:
    def __init__(self, name, age):
        """属性没有封装"""
        self._name = name
        self._age = age

damu = Person("大牧")
print(damu._name)
# 约定封装,这样的访问 代码是正确的,逻辑上错误!
# IDE工具警告 Access to a protected member _name of a class

语法规则,强制封装

当数据的安全性有很高的要求,通过语法规则进行属性或者方法的私有化操作,语法上使用两个下划线开头的属性和方法,是一种语法规则上的私有化操作,理论外界不能直接调用执行。

class Person:
    def __init__(self, name, age):
        """属性没有封装"""
        self.__name = name
        self.__age = age

damu = Person("大牧")
print(damu.__name)
# 程序报错
# AttributeError: 'Person' object has no attribute '__name'

强制封装,解释器在内存中对两个下划线开头的属性或者方法进行了转换,解释成了如下的语法:
_类名__属性名称 当我们使用 引用变量._类名__属性名称 仍可以直接访问私有属性,但是不推荐这样的
访问方式。

完整的封装代码

class Person:
    def __init__(self, name):
        """私有属性的封装"""
        self.__name = name

    def get_name(self):
        """获取私有属性值方法"""
        return self.__name

    def set_name(self, name):
        """修改私有属性值方法"""
        self.__name = name

damu = Person("damu")

print(damu.__name)
# AttributeError: 'Person' object has no attribute '__name'

print(damu.get_name())
# damu

damu.set_name("damu2")
print(damu.get_name())
# damu2

封装的好处

封装体现了生活中数据的隐私性,在操作过程中如果对于对象中的数据有安全性要求的前提下,通过封装实现了对数据的保护。

在有数据安全性要求的项目中,封装是实现数据保护的最直接最简单的操作语法

封装的适用场景

  • 简单项目,数据没有安全性要求
    不使用封装 (非要封装-也没有问题-开发效率过低-过度设计)

  • 传统项目,公司中以前开发的遗留项目
    使用约定封装[遵循项目组规范,观察代码中的编码规范(优先)]

  • 新项目,公司中开发的新项目对数据安全性有一定的要求
    使用语法上的封装,实现数据保护的目的

  • 企业项目,很少直接编写底层类型封装操作
    实际项目中,通常使用成熟稳定的框架,声明类型中不需要编写封装的代码,框架中已经将类中的属性进行了自定封装操作