一、组合    

   解决类与类之间代码冗余问题有两种解决方案:1、继承 2、组合

1、继承:描述的是类与类之间,什么是什么的关系

2、组合:描述的是类与类之间的关系,是一种什么有什么关系
 一个类产生的对象,该对象拥有一个属性,这个属性的值是来自于另外一个类的对象

class Date:
def __init__(self,year,mon,day):
self.year = year
self.mon = mon
self.day = day def tell_birth(self):
print('出生年月日<%s-%s-%s>' % (self.year, self.mon, self.day)) class OldboyPeople:
school = 'oldboy' def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex class OldboyTeacher(OldboyPeople):
def __init__(self,name,age,sex,level,salary):
super().__init__(name,age,sex)
self.level=level
self.salary=salary def change_score(self):
print('teacher %s is changing score' %self.name) class Oldboystudent(OldboyPeople):
def __init__(self,name,age,sex,course,):
super().__init__(name,age,sex,)
self.course=course def choose(self):
print('student %s choose course' %self.name) tea1=OldboyTeacher('egon',18,'male',9,3.1)
date_obj=Date(2000,1,1)
# date_obj.tell_birth() tea1.birth=date_obj
# print(tea1.birth)
# tea1.birth.tell_birth()
# tea1.change_score() stu1=Oldboystudent('张三',16,'male','linux')
stu1.birth=Date(2002,3,3)
stu1.birth.tell_birth()

二、封装  

1、什么是封装

装就是把一堆属性存起来,封的概念就把这些属性给隐藏起来
强调:封装单从字面意思去看等同于隐藏,但其实封装绝对不是单纯意义的隐藏

2、为什么要用封装

    1. 封装数据属性的目的:把数据属性封装起来,然后需要开辟接口给类外部的使用者使用,好处是
       我们可以在接口之上添加控制逻辑,从而严格空间访问者对属性的操作

      class People:
      def __init__(self,name,age):
      self.__name=name
      self.__age=age def tell_info(self):
      # u=input('user>>: ').strip()
      # p=input('pwd>>: ').strip()
      # if u == 'egon' and p == '123':
      print(self.__name,self.__age) def set_info(self,name,age):
      if type(name) is not str:
      raise TypeError('用户名必须为str类型')
      if type(age) is not int:
      raise TypeError('年龄必须为int类型')
      self.__name=name
      self.__age=age p=People('egon',18) # p.tell_info()
      # p.tell_info() # p.set_info('EGON',19)
      # p.tell_info() # p.set_info(353535353535353535,20)
      p.set_info('EGON','20')
    2. 封装函数属性的目的:为了隔离复杂度      
class ATM:
def __card(self):
print('插卡')
def __auth(self):
print('用户认证')
def __input(self):
print('输入取款金额')
def __print_bill(self):
print('打印账单')
def __take_money(self):
print('取款') def withdraw(self):
self.__card()
self.__auth()
self.__input()
self.__print_bill()
self.__take_money() obj=ATM()
obj.withdraw()

        3.   封装的终极奥义:明确地区分内外,对外是隐藏的,对内是开放的

3、如何用封装

  1. 其实这种隐藏只是一种语法上的变形,对外不对内
     为一个属性名加__开头(注意不要加__结尾),会在类定义阶段将属性名统一变形:_自己的类名__属性名

    1. class Foo:
      __x=1111 #_Foo__x=1111
      def __init__(self,y):
      self.__y=y #self._Foo__y=y def __f1(self): #_Foo__f1
      print('Foo.f1') def get_y(self):
      print(self.__y) # print(self._Foo__y) obj=Foo(22222)
      # print(obj.x)
      # print(obj.__x)
      # obj.__f1()
      # print(obj.y)
      # print(obj.__y)
      # print(Foo.__dict__)
      # print(obj._Foo__x)
      # print(obj._Foo__y)
      # obj._Foo__f1() # obj.get_y()
  2. 这种语法意义上变形,只在类定义阶段发生一次,类定义之后,新增的__开头的属性都没有变形的效果
  3. 如果父类不想让子类覆盖自己的方法,可以在方法名前加__开头
    1. class Foo:
      def __f1(self): #_Foo__f1
      print('Foo.f1') def f2(self):
      print('Foo.f2')
      self.__f1() #obj._Foo__f1() class Bar(Foo):
      def __f1(self): #_Bar__f1
      print("Bar.f1") obj=Bar() obj.f2()

4月13日 python学习总结 组合与封装的更多相关文章

  1. 6月13日 python学习总结 Django框架

    1. 内容回顾 1. 基础必会三件套 from django.shortcuts import HttpResponse, render, redirect - HttpResponse(" ...

  2. 4月2日 python学习总结

    昨天内容回顾: 1.迭代器 可迭代对象: 只要内置有__iter__方法的都是可迭代的对象 既有__iter__,又有__next__方法 调用__iter__方法==>得到内置的迭代器对象 调 ...

  3. 4月8日 python学习总结 模块与包

    一.包 #官网解释 Packages are a way of structuring Python's module namespace by using "dotted module n ...

  4. 4月12日 python学习总结 继承和派生

    一.继承 什么是继承:   继承是一种新建类的方式,在python中支持一个子类继承多个父类   新建类称为子类或派生类   父类可以称之为基类或者超类   子类会遗传父类的属性 2.  为什么继承 ...

  5. 4月11日 python学习总结 对象与类

    1.类的定义 #类的定义 class 类名: 属性='xxx' def __init__(self): self.name='enon' self.age=18 def other_func: pas ...

  6. 6月15日 python学习总结 Django模板语言相关内容

    Django模板语言相关内容   Django模板系统 官方文档 常用语法 只需要记两种特殊符号: {{  }}和 {% %} 变量相关的用{{}},逻辑相关的用{%%}. 变量 {{ 变量名 }} ...

  7. 5月31日 python学习总结 JavaScript概述

    JavaScript概述 ECMAScript和JavaScript的关系 1996年11月,JavaScript的创造者--Netscape公司,决定将JavaScript提交给国际标准化组织ECM ...

  8. 5月14日 python学习总结 视图、触发器、事务、存储过程、函数、流程控制、索引

    一.视图 1.什么是视图 视图就是通过查询得到一张虚拟表,然后保存下来,下次用的直接使用即可 2.为什么要用视图 如果要频繁使用一张虚拟表,可以不用重复查询 3.如何用视图 create view t ...

  9. 4月9日 python学习总结 模块

    1.XML模块 xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单,不过,古时候,在json还没诞生的黑暗年代,大家只能选择用xml呀,至今很多传统公司如金融 ...

随机推荐

  1. 从MVC到DDD的架构演进

    DDD这几年越来越火,资料也很多,大部分的资料都偏向于理论介绍,有给出的代码与传统MVC的三层架构差异较大,再加上大量的新概念很容易让初学者望而却步.本文从MVC架构角度来讲解如何演进到DDD架构. ...

  2. 继承及属性查找+super()和mro()+多态

    继承及属性查找+super()和mro()+多态 一. ★继承 1. 什么是继承? 继承就是新建类的一种方式,新建的类我们称为子类或者叫派生类,被继承的类我们称为父类或者基类 子类可以使用父类中的属性 ...

  3. 大话PHP设计模式笔记

    针对PHP的设计模式进行总结记录. 顺带,我会在后面把我整理的一整套CSS3,PHP,MYSQL的开发的笔记打包放到百度云,有需要可以直接去百度云下载,这样以后你们开发就可以直接翻笔记不用百度搜那么麻 ...

  4. CentOS7 下 ldap 部署

    环境准备 # 关闭防火墙以及selinux,生产环境中,以实际需求为准 [root@localhost ~]# hostnamectl --static set-hostname ldap-serve ...

  5. 利用终端统计 Xcode代码数量命令

    直接利用终端命令进入工程文件夹然后写下或复制以下命令 find . -name "*.m" -or -name "*.h" -or -name "*. ...

  6. 为什么三层架构中业务层(service)、持久层(dao)需要使用一个接口?

    为什么三层架构中业务层(service).持久层(dao)需要使用一个接口? 如果没有接口那么我们在控制层使用业务层或业务层使用持久层时,必须要学习每个方法,若哪一天后者的方法名改变了则直接影响到前面 ...

  7. HP 电脑 - Windows 10 如何设置虚拟内存

    HP 电脑 - Windows 10 如何设置虚拟内存(新)   适用于安装 Windows 10 系统的 HP 电脑 Windows 中运用了虚拟内存技术,即分出一部分硬盘空间来充当内存使用.当内存 ...

  8. 利用Node.js编写跨平台的spawn语句

    node const child = cp.spawn('npm', ['run', 'build']); 报错 events.js:182 throw er; // Unhandled 'error ...

  9. Pycharm:一直connecting to console的解决办法

    方法一: 1.打开Anaconda cmd(也就是Anaconda Prompt,在启动栏Anaconda目录里应该有)2.输入echo %PATH% 获得PATH value3.在PyCharm中, ...

  10. 报错:net::err_unknown_url_scheme的解决办法

    在项目中设置了api请求和web页面请求的地址,如下图: 控制台报错,如下图: 问题是:没有加入"http://"这个头,因此访问不到. 解决办法: 再次访问正常