组合

what?   组合是指一个对象中,包含另一个或多个对象。

why?      减少代码的冗余。

How?     在类中加入其他类的对象,实现跨类对象之间的联动。

耦合度  软件设计要 高内聚,低耦合。

耦合度越高,程序的可扩展性越低

耦合度越低,程序的可扩展性越高

继承与组合的区别:

继承代表【是】的关系,是类和类之间的关系,老师类是人类,学生类是人类。子类和父类是从属关系。

组合代表【有】的关系,是对象和对象之间的关系,老师对象 有 课对象,学生对象 有 课对象。表示拥有某种属性或者方法。

组合

组合的精髓在与将一个对象作为某个类的特有属性,然后通过该特有属性(赋的是其他类的对象的值)再去调用对象所在类的方法,实现多种功能的拼接。

举例:

  1. # _*_ coding: gbk _*_
  2. # @Author: Wonder
  3. '''
  4. 练习需求:
  5. 选课系统:
  6. 1.有学生、老师类,学生与老师有属性 “名字、年龄、性别、
  7.  
  8. 课程”,
  9. 2.有方法 老师与学生可以添加课程,
  10.  
  11. 打印学习/教授课程。
  12.  
  13. # 组合实现
  14. '''
  15.  
  16. class People:
  17. def __init__(self, name, age, gender):
  18. self.name = name
  19. self.age = age
  20. self.gender = gender
  21.  
  22. def add_course(self, course_obj):
  23. self.course_list.append(course_obj)
  24.  
  25. def course_info(self):
  26. for course_obj in self.course_list:
  27. course_obj.show()#通过对象去找该对象能取到的方法
  28.  
  29. class Teacher(People):
  30. def __init__(self, name, age, gender):
  31. super().__init__(name, age, gender)
  32. self.course_list = [] #存放交互对象的容器
  33.  
  34. class Student(People):
  35. def __init__(self, name, age, gender):
  36. super().__init__(name, age, gender)
  37. self.course_list = []
  38.  
  39. class Course:
  40. def __init__(self, course_name, course_price, course_cycle):
  41. self.course_name = course_name
  42. self.course_price = course_price
  43. self.course_cycle = course_cycle
  44.  
  45. def show(self):
  46. print(f'''
  47. =======选的课为:=======
  48. course_name = {self.course_name}
  49. course_price = {self.course_price}
  50. course_cycle = {self.course_cycle}
  51. ''')
  52.  
  53. t1 = Teacher('abc', 19, 'male')
  54. python_obj = Course('PYTHON', 10000, '6month') # 统一称之为course_obj
  55. go_obj = Course('GO', 5000, '4month')
  56. t1.add_course(python_obj)
  57. t1.add_course(go_obj)
  58. t1.course_info() t1永远只会调用自己本身或者父类的函数,组合的类,由组合的对象去调用

  

封装

什么是封装:将一堆属性和方法封装到对象中去,可以通过【对象名.】的方式进行调用。

封装使得对数据的提取更加方便。

封装中的访问限制机制

what   凡是在类内部定义的属性和方法,以__开头的属性和方法,都会被限制,外部不能直接使用该属性原型。类似于将该属性或方法隐藏起来了。通过在属性或函数前面加上 _ _将该属性或方法隐藏起来,   本质上是一种变形操作。    _ _name  等价于  _ 类名_ _ 属性名

why   可以将一些隐私数据隐藏起来,不让外部轻易获取。

    可以将一堆数据封装成接口,让用户直接调用,并通过相应的逻辑,最后将数据返回。

how :如果知道类名以及被隐藏是数据或者方法名,可以通过【_类名__属性/方法名】进行调用

例如  :

  1. # _*_ coding: gbk _*_
  2. # @Author: Wonder
  3. class People:
  4. __school = 'HEU'
  5.  
  6. def __init__(self, name, age, gender):
  7. self.__name = name
  8. self.__age = age
  9. self.__gender = gender
  10.  
  11. def __show(self):
  12. print('隐藏了吗')
  13.  
  14. human1 = People('wonder', 19, 'male')
  15. print(human1.__school) #People' object has no attribute '__school'
  16. print(human1._People__school) #HEU
  17.  
  18. print(human1.__name) # AttributeError: 'People' object has no attribute '__name'
  19. print(human1._People__name) #wonder
  20.  
  21. human1.__show() # AttributeError: 'People' object has no attribute '__show'
  22. human1._People__show() # 隐藏了吗

  

用_ _隐藏的主要目的是想将属性或者方法限制在类中使用,不想被外界调用。

property本质上是一个装饰器,用来装饰类内部的方法(在被装饰方法上方,使用语法糖@property,进而将  原先的【类名.方法名()】调用方式改变为【类名.方法名】

如果被property装饰过的方法,想要改变他的值,只可以通过@被装饰方法名.setter以及@被装饰方法名.deleter进行修改和删除操作。

  1. # _*_ coding: gbk _*_
  2. # @Author: Wonder
  3. # class Securty:
  4. # def __init__(self, name, gender, height, weight):
  5. # self.__name = name
  6. # self.gender = gender
  7. # self.height = height
  8. # self.weight = weight
  9. #
  10. # def hw(self):
  11. # return (self.height + self.weight)
  12. #
  13. # @property
  14. # def sex(self):
  15. # return self.gender
  16. #
  17. # @property
  18. # def namey(self):
  19. # return self.__name
  20.  
  21. # s1 = Securty('wonder', 'male', 190, 200)
  22. # print(s1.hw()) # 390
  23. # print(s1.sex()) # TypeError: 'str' object is not callable
  24. # print(s1.sex) # male
  25. # print(s1.namey) # wonder

  

__name是可以被return出来的。见上面红色背景的语句及执行结果。

  1. # 想修改或删除被property装饰的属性
  2. class Sure:
  3. def __init__(self, name, ):
  4. self.__name = name
  5.  
  6. @property
  7. def namey(self):
  8. return self.__name
  9.  
  10. @namey.setter
  11. def namey(self, value):
  12. if not isinstance(value, str):
  13. raise TypeError('FUCK_NO')
  14. self.__name = value
  15.  
  16. @namey.deleter
  17. def namey(self):
  18. # del self.__name # 执行删除操作
  19. # 如果将改为raise TypeError('forbidden')
  20. raise TypeError('forbidden')
  21.  
  22. name1 = Sure('GOOGLE')
  23. print(name1.namey) # GOOGLE
  24. name1.namey = 'YAHOO' # 修改值操作
  25. print(name1.namey) # YAHOO
  26. del name1.namey #删除操作
  27. print(name1.namey) # 如果删除了,则会报错AttributeError: 'Sure' object has no attribute '_Sure__name'。否则还是YAHOO

  

CSIC_716_20191127【组合,封装、类的私有属性方法、property装饰器】的更多相关文章

  1. 通过decorators = [,] 的形式给类中的所有方法添加装饰器

    给类添加装饰器有多种方法: 1.可以在类中的某个方法上边直接@添加,这个粒度细.无需详细介绍 2.也可以在类中通过 decorators=[, ]的形式添加,这样的话,类中的所有方法都会被一次性加上装 ...

  2. 面向对象之封装 及@property装饰器使用

    目录 封装 1.封装的定义 2.封装的目的: 3.封装的三种方式 4.封装的优点 5.访问限制(封装) @property 装饰器 属性property底层实现 封装 1.封装的定义 将复杂的丑陋的, ...

  3. Python类总结-封装(私有属性,方法)

    封装基础 广义上面向对象的封装:代码的保护,面向对象的思想本身就是一种封装 只让自己的对象能调用自己类中的方法 狭义上的封装-面向对象三大特性之一(私有变量,用公有的方法封装私有属性,方法叫封装) 把 ...

  4. 访问类的私有属性(RTTI和模仿类2种方法)

    如何访问类的私有属性? 下面以 TPathData 为例,它有一个私有属性 PathData,储存了每一个曲线点,但一般无法修改它,需要利用下面方法,才能访问修改(若有更好的方法,歡迎分享): 一.利 ...

  5. python 类的私有属性和方法 (转载)

    转载:http://www.runoob.com/python/python-object.html 类属性与方法 类的私有属性 __private_attrs:两个下划线开头,声明该属性为私有,不能 ...

  6. Java使用PropertyDescriptor获取实体类中私有属性的值,并给私有属性赋值

    大家都知道Java类中的私有的(private)属性是获取不到的(即使使用继承依然获取不到),那如果非要获取私有属性的值怎么办呢?一般的做法是将该java类封装称为一个JavaBean,即封装该私有属 ...

  7. python面向编程:类的组合、封装、property装饰器、多态

    一.组合 二.封装 三.propert装饰器 四.多态 一.组合 ''' 1. 什么是组合 一个对象的属性是来自于另外一个类的对象,称之为组合 2. 为何用组合 组合也是用来解决类与类代码冗余的问题 ...

  8. Python类的私有属性

    class Bar(object): __age = 18 sex = 'male' def __init__(self, ): pass def f(self): print(self.__age) ...

  9. 面向对象之组合、封装、多态、property装饰器

    概要: 组合 封装 property装饰器 多态 Python推崇鸭子类型:解耦合,统一标准(不用继承) 1. 组合 继承:会传递给子类强制属性 组合:解耦合,减少占用内存.如:正常继承,如果一个班级 ...

随机推荐

  1. 7G

  2. 解决mybatisplus saveBatch 或者save 无法插入主键问题

    解决mybatisplus saveBatch 或者save 无法插入主键问题 通过跟踪源码后得出结论,由于插入的表的主键不是自增的,而是手动赋值的,所以在调用saveBatch 执行的sql语句是没 ...

  3. CSIC_716_20191216【pymysql模块】

    强调:mysql要设置严格模式,在my.ini 配置文件中 sql-mode="strict_trans_tables,only_full_group_by"    ,设置完要重启 ...

  4. 让微信小程序每次请求的时候不改变session_id的方法

    让微信小程序每次请求的时候不改变session_id的方法 每次微信小程序请求的时候都会改变session id, 还好他的请求方法内可以设置header头 所以只需要在启动程序后第一次请求服务器获得 ...

  5. Android 为点击事件添加震动效果

    Android 点击Button 实现震动效果 学习自:网络 Overview 在Android 的点击效果中,遇到震动效果的还是很多的. 接下来就让我们看一下如何实现震动效果. 所需要的权限 如果我 ...

  6. applicationContext-redis.xml配置文件

    <?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.spr ...

  7. Dart编程实例 算术操作符

    Dart编程实例 算术操作符 void main() { var num1 = 101; var num2 = 2; var res = 0; res = num1+num2; print(" ...

  8. JavaWeb开发中遇到的错误:org.apache.catalina.core.StandardWrapperValve invoke

    org.apache.catalina.core.StandardWrapperValve invoke 今天写代码,竟然接连遇到这个异常好几次.debug几个小时才弄明白,晕. 上网找了些拼凑下做个 ...

  9. jmeter之-图形监控

    一.安装 https://jmeter-plugins.org/downloads/old/ 下载JMeterPlugins-Standard-1.4.0(监听器-图形界面)和ServerAgent- ...

  10. LYOI2018 Hzy's Planets

    题目描述: 删掉一个边,看其是否联通,图是一棵树,在线,多组询问. 数据范围: \(n \leq 10^5\) 题解: (休闲一下) 这种直接用dfs序即可,直接讨论连边的位置就行. 还有一种做法懒得 ...