一、组合    

   解决类与类之间代码冗余问题有两种解决方案: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. python篇第5天【变量】

    第4天加班 多个变量赋值 Python允许你同时为多个变量赋值.例如: a = b = c = 1 以上实例,创建一个整型对象,值为1,三个变量被分配到相同的内存空间上. 您也可以为多个对象指定多个变 ...

  2. interface中setup_time和hold_time

    interface中的setup_time和hold_time input:约束input信号提前T时间采样,然后在时钟沿更新到input信号上. output:约束output信号,在时钟沿T时间后 ...

  3. 乘风破浪,遇见未来元宇宙(Metaverse)之进入元宇宙世界,虚拟数字人行业洞察报告

    正值元宇宙热潮,虚拟数字人兴起 作为⼀个新兴领域,虚拟数字⼈已经引起市场和资本的⾼度关注,截⾄目前据不完全统计,全球范围已有500+虚拟数字人相关项目获得融资,融资总额超10亿美元,并且融资项目和总额 ...

  4. Python中模块调用说明

    1 import test # 导入test模块 2 3 print(test.a) # 使用"模块.变量"调用模块中的变量 4 5 test.hi() # 使用"模块. ...

  5. ansible中的hostvars

    首先来看一个例子:假设我想得到主机IP为172.25.250.9的完全限定域名(FQDN),但是我无法登录该主机,那么就可以用本机里面的hostvars魔法变量(后面会分享我对魔法这个词的理解)这个字 ...

  6. IP网络主动测评系统

    一.IT网络运维面临的挑战 1. 网络性能可视化 • 与公有云和SaaS平台连接的可靠性 • 广域网线路性能 • 互联网专线性能 2.诊断工具 • 现场无IT工程师覆盖 • 诊断的人力费用 • 网络与 ...

  7. proto编译组件使用

    proto编译组件使用 前提:所有组件已经安装好,包括: protoc protoc-gen-go protoc-gen-grpc-gateway protoc-gen-swagger 怎么装再开一篇 ...

  8. Java笔记——循环语句

    Java笔记--循环语句     1. while语句 规律: 1. 首先计算表达式的值. 2. 若表达式为真,则执行循环语法,直至表达式为假,循环结束.   while(表达式) 语句; 例如: i ...

  9. 【C#基础知识】C#控制台程序入口函数 Main(string[] args) 参数详解

    测试环境vs2019+.net5.0 请看 :https://cloud.tencent.com/developer/article/1507934 本测试环境vs2022+.net6.0 +wind ...

  10. 接口java.util.Map的四个实现类HashMap Hashtable LinkedHashMap TreeMap

    java中HashMap,LinkedHashMap,TreeMap,HashTable的区别 :java为数据结构中的映射定义了一个接口java.util.Map;它有四个实现类,分别是HashMa ...