Python面向对象(三)—封装

封装

定义

1.数据角度讲,将一些基本数据类型复合成一个自定义类型。

2.行为角度讲,向类外提供必要的功能,隐藏实现的细节。

封装数据:多个数据 --> 一个种数据(新类型)

例如:学生类(姓名/年龄..) 汽车(品牌/价格..)

适用性:多种信息描述同一种事物.

3.设计角度讲

(1)分而治之

-- 将一个大的需求分解为许多类,每个类处理一个独立的功能。 (类要小而精,拒绝大而全.)

-- 拆分好处:便于分工,便于复用,可扩展性强。

(2) 封装变化

-- 变化的地方独立封装,避免影响其他类。分解的度,识别变化点,单独做成类.)

(3) 高 内 聚

-- 类中各个方法都在完成一项任务(单一职责的类)类内部,高度聚集.完成一个变化点。)

(4) 低 耦 合

-- 类与类的关联性与依赖度要低(每个类独立),让一个类的改变,尽少影响其他类。(类与类关系,尽量松散。)

[例如:硬件高度集成化,又要可插拔]

最高的内聚莫过于类中仅包含1个方法,将会导致高内聚高耦合。

最低的耦合莫过于类中包含所有方法,将会导致低耦合低内聚。

作用

简化编程,使用者不必了解具体的实现细节,只需要调用对外提供的功能。

松散耦合,降低了程序各部分之间的依赖性。

数据和操作相关联,方法操作的是自己的数据。

1.作用:无需向类外提供的成员,可以通过私有化进行屏蔽。

2.做法:命名使用双下划线开头。

3.本质:障眼法,实际也可以访问。

私有成员

私有成员的名称被修改为:_类名__成员名,可以通过_dict_属性或dir函数查看。

__slots__

作用:限定一个类创建的实例只能有固定的实例变量,不能再额外添加。

语法:

在类中定义

__slots__ = (“变量名1”,”变量名2”…..)

1.说明:含有__slots__属性的类所创建的对象没有__dict__属性, 即此实例不用字典来存储对象的实例属性。

2.优点:访止用户因错写属性的名称而发生程序错误。

3.缺点:丧失了动态语言可以在运行时为对象添加变量的灵活性。

class Wife:
  __slots__ = ("name","__age")
  def __init__(self, name, age):
    self.name = name
    self.age = age

  @property
  def age(self):
    return self.__age

  @age.setter
  def age(self,value):
    self.__age = value

w01 = Wife("丽丽",26)
# 因为类中定义了__slots__,所以不能在类外添加新数据.
# w01.sex = "女"
# w01.nmae = "莉莉"
print(w01.age)

属性@property

公开的实例变量,缺少逻辑验证。私有的实例变量与两个公开的方法相结合,又使调用者的操作略显复杂。而属性可以将两个方法的使用方式像操作变量一样方便。

1.定义:

class Wife:
  """
    老婆
  """
  def __init__(self, name, age):
    self.name = name
    self.age = age

  @property # 拦截读取操作
  def age(self):
    return self.__age

  @age.setter# 拦截写入操作
  def age(self, value):
    if 28 <= value <= 32:
      self.__age = value
    else:
      raise Exception("超出年龄,我不要")

  # 拦截 对数据的操作,转为调用读写方法.
  #age = property(get_age, set_age)


w01 = Wife("丽丽", 30)
print(w01.age)
print(w01.__dict__)

2.调用:

对象.属性名 = 数据

变量 = 对象.属性名

3.说明:

-- 通常两个公开的属性,保护一个私有的变量。

-- @property 负责读取,@属性名.setter 负责写入

-- 只写:属性名= property(None, 写入方法名)

posted @ 2019-05-19 00:01  maplethefox  阅读(374)  评论(0编辑  收藏  举报