Python学习记录8-继承2
继承
- 单继承和多继承
- 单继承:每个类只能继承一个类
- 多继承:每个类允许继承多个类
 
    >>> class A():
            pass
    >>> class B(A):
            pass
    >>> class C(B,A):
            pass
    >>> print(A.__mro__)
    >>> print(B.__mro__)
    输出:
    (<class '__main__.A'>, <class 'object'>)
    (<class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
    # 子类可以直接拥有父类的属性和方法,私有属性和方法除外
    >>> class Fish():
            def __init__(self, name):
                self.name = name
            def swim(self):
                print('{} can swimming......'.format(self.name))
    >>> class Bird():
            def __init__(self, name):
                self.name = name
            def fly(self):
                print('{} can fly......'.format(self.name))
    >>> class Person():
            def __init__(self, name):
                self.name = name
            def work(self):
                print("Working......")
    # 单继承的例子
    >>> class Student(Person):
            def __init__(self, name):
                self.name = name          
    # 多继承
    >>> class SuperMan(Person, Bird, Fish):
            def __init__(self, name):
                self.name = name   
    >>> s = SuperMan('小明')
    >>> s.fly()
    >>> s.swim() 
    输出:
    小明 can fly......
    小明 can swimming......   
- 单继承和多继承的优缺点 - 单继承:
- 传承有序逻辑清晰语法简单隐患少
- 功能不能无限扩展,只能在当前唯一的继承链中扩展
 
- 多继承:
- 优点:类的功能扩展方便
- 缺点:继承关系混乱
 
 
- 单继承:
- 菱形继承/钻石继承 - 多个子类继承自同一个父类,这些子类又被同一个类继承,于是继承关系图形成一个菱形图谱
- MRO
- 关于多继承的MRO
- MRO就是多继承中,用于保存继承顺序的一个列表
- python本身采用C3算法来做多继承的菱形继承进行计算的结果
- MRO列表的计算原则:
- 子类永远在父类前面
- 如果多个父类,则根据继承语法中括号内类的书写顺序存放
- 如果多个类继承了同一个父类,孙子类中只会选取继承语法括号中第一个父类的父类
 
 
 
    # 菱形问题
    >>> class A():
            pass
    >>> class B(A):
            pass
    >>> class C(A):
            pass
    >>> class D(B,C):
            pass
- 构造函数
- 在对象进行实例化的时候,系统自动调用的一个函数叫构造函数,通常此函数用来实例化对象进行初始化,顾名构造函数,在python中叫魔术函数、魔法函数。
- 构造函数一定要有,如果没有,则自动向上查找,按照MRO顺序,直到找到为止
 
    # 构造函数例子
    >>> class Person():
            # 对Person类进行实例化的时候
            # 姓名要确定
            # 年龄得确定
            # 地址肯定有
            def __init__(self):
                self.name = "NoName"
                self.age = 18
                self.address = 'earth'
                print("I am a Student")
    # 实例化一个人
    >>> p = Person()
    >>> print(p.__dict__)    
    输出:
    I am a Student
    {'name': 'NoName', 'age': 18, 'address': 'earth'}
    ---------------------------------------------------------------------------------------------------
     # 构造函数的调用顺序 -1
    # 如果子类没有写构造函数,则自动向上查找,直到找到为止
    >>> class A():
            def __init__(self):
                print("A")
    >>> class B(A):
            def __init__(self):
                print("B")
    >>> class C(B):
            pass
    # 此时,首先查找C的构造函数
    # 如果没有,则向上按照MRO顺序查找父类的构造函数,直到找到为止
    >>> c = C() # C类没有构造函数 找C的父类B 找到了 然后停止 不再向上找
    ---------------------------------------------------------------------------------------------------
    # 构造函数的调用顺序 -2
    >>> class A():
            def __init__(self):
                print("A")
    >>> class B(A):
            def __init__(self, name):
                print("B")
                print(name)
    >>> class C(B):
            pass
    # 此时,首先查找C的构造函数
    # 如果没有,则向上按照MRO顺序查找父类的构造函数,直到找到为止
    # 此时,会出现参数结构不对应错误
    # c = C() # 此处 C类没有构造函数 向上找到C的父类B的构造函数 但B类构造函数需要两个参数
    >>> cc = C('哈哈')
    输出:
    B
    哈哈
    ---------------------------------------------------------------------------------------------------
    # 构造函数的调用顺序 -3
    >>> class A():
            def __init__(self):
                print("A")
    >>> class B(A):
            def __init__(self, name):
                print("B")
                print(name)
    >>> class C(B):
            # c中想扩展B的构造函数,
            # 即调用B的构造函数后再添加一些功能
            # 有两种方法实现
            ''' 
            # 第一种是通过父类名调用
            def __init__(self, name):
                # 首先调用父类的构造函数
                B.__init__(self, name)
                #其次,再增加自己的功能
                print("这是C中附加的功能")
            '''
            # 第二种,使用super调用
            def __init__(self, name):
                # 首先调用父类构造函数
                super(C, self).__init__(name)
                # 其次,再增加自己的功能
                print("这是C中附加的功能")
    >>> c = C("我是C") 
    输出:
    B
    我是C
    这是C中附加的功能
多态
- 多态就是同一个对象在不同情况下有不同的状态出现 
- 多态不是语法,是一种设计思想 
- 多态性:一种调用方式,不同的执行效果 
- 多态:同一事物的多种形态,动物分为人类、狗类、猪类 
- Mixin设计模式 - 主要采用多继承方法对类的功能进行扩展
 
- 我们使用多继承语法来是吸纳Mixin 
- 使用Mixin实现多继承的时候要非常小心 - 首先他必须表示某一单一功能,而不是某个物品
- 职责必须单一,如果有多个功能,则写多个Mixin
- Mixin不能依赖于子类的实现
- 子类即使没有继承这个Mixin类,也能照样工作,只是缺少了某个功能
 
- 优点 - 使用Minxin可以在不对类进行任何修改的情况下,扩充功能
- 可以方便的组织和维护不同功能组件的划分
- 可以根据需要任意调整功能类的组合
- 可以避免创建很多新的类,导致类的继承混乱
 
    # Mixin案例
    >>> class Person():
            name = '小明'
            age =18
            def eat(self):
                print("EAT....")
            def drink(self):
                print("Drink....")
            def sleep(self):
                print("SLEEP....")     
    >>> class Teacher(Person):
            def work(self):
                print("WORK....")   
    >>> class Teacher(Person):
            def work(self):
                print("WORK....")    
    >>> class Student(Person):
            def study(self):
                print("STUDY....")  
    >>> class Tutor(Teacher, Student):
            pass
    >>> t = Tutor()
    >>> print(Tutor.__mro__)
    >>> print(t.__dict__)
    >>> print(Tutor.__dict__)
    >>> print("*" * 20)
    >>> class TeacherMixin():
            def work(self):
                print("Work")
    >>> class StudentMixin():
            def study(self):
                print("Study")
    >>> class TutorM(Person, TeacherMixin, StudentMixin):
            pass
    >>> tt = TutorM()
    >>> print(TutorM.__mro__)
    >>> print(tt.__dict__)
    >>> print(TutorM.__dict__)
    输出:
    (<class '__main__.Tutor'>, <class '__main__.Teacher'>, <class '__main__.Student'>, <class '__main__.Person'>, <class 'object'>)
    {}
    {'__module__': '__main__', '__doc__': None}
    ********************
    (<class '__main__.TutorM'>, <class '__main__.Person'>, <class '__main__.TeacherMixin'>, <class '__main__.StudentMixin'>, <class 'object'>)
    {}
    {'__module__': '__main__', '__doc__': None}
Python学习记录8-继承2的更多相关文章
- Python学习记录day7
		目录 Python学习记录day7 1. 面向过程 VS 面向对象 编程范式 2. 面向对象特性 3. 类的定义.构造函数和公有属性 4. 类的析构函数 5. 类的继承 6. 经典类vs新式类 7. ... 
- Python学习记录day6
		title: Python学习记录day6 tags: python author: Chinge Yang date: 2016-12-03 --- Python学习记录day6 @(学习)[pyt ... 
- Python学习记录day5
		title: Python学习记录day5 tags: python author: Chinge Yang date: 2016-11-26 --- 1.多层装饰器 多层装饰器的原理是,装饰器装饰函 ... 
- Python学习记录day8
		目录 Python学习记录day8 1. 静态方法 2. 类方法 3. 属性方法 4. 类的特殊成员方法 4.1 __doc__表示类的描述信息 4.2 __module__ 和 __class__ ... 
- Python学习记录:括号配对检测问题
		Python学习记录:括号配对检测问题 一.问题描述 在练习Python程序题的时候,我遇到了括号配对检测问题. 问题描述:提示用户输入一行字符串,其中可能包括小括号 (),请检查小括号是否配对正确, ... 
- 实验楼Python学习记录_挑战字符串操作
		自我学习记录 Python3 挑战实验 -- 字符串操作 目标 在/home/shiyanlou/Code创建一个 名为 FindDigits.py 的Python 脚本,请读取一串字符串并且把其中所 ... 
- 我的Python学习记录
		Python日期时间处理:time模块.datetime模块 Python提供了两个标准日期时间处理模块:--time.datetime模块. 那么,这两个模块的功能有什么相同和共同之处呢? 一般来说 ... 
- Python  学习记录
		记录一些 学习python 的过程 -------------------------------------- 1. 初始学习 @2013年10月6日 今天开始学习python 了 遇到好多困难但是 ... 
- python学习记录_IPython基础,Tab自动完成,内省,%run命令_
		这是我第一次写博客,之前也有很多想法,想把自己所接触的,以文本的形式储存,总是没有及时行动.此次下定决心,想把自己所学,所遇到的问题做个记录共享给诸位,与此同时自己作为备忘,感谢各位访问我的博 ... 
- Python学习记录----数据定义
		摘要: 描述Python中数据定义格式,需要注意的东东. 一 数据声明 Python木有一般语言的具体数据类型,像char,int,string这些通通木有.这有点像javascript,但又不同,j ... 
随机推荐
- Spring Cloud(8):日志及分布式跟踪(Sleuth&Zipkin)
			简介 在微服务架构中,项目中前端发起一个请求,后端可能跨几个服务调用才能完成这个请求.如果系统越来越庞大,服务之间的调用与被调用关系就会变得很复杂,那么这时候我们需要分析具体哪一个服务出问题了就会显得 ... 
- Java如何获取ResultSet结果中的每一列的数据类型
			示例代码片段: ResultSet resultSet = statement.executeQuery(sql); ResultSetMetaData metaData = resultSet.ge ... 
- 【Leetcode_easy】1108. Defanging an IP Address
			problem 1108. Defanging an IP Address solution: class Solution { public: string defangIPaddr(string ... 
- C入门笔记
			教程总体概括:Mac OS X系统简介:C语言:OC语言:Foundation:iOS开发:项目实战. 3.第一个c语言程序#include <stdio.h>//预处理指令:在编译之前执 ... 
- WordPress的Bootstrap面包屑导航
			<ol class="breadcrumb"> 当前位置: <li><a href="<?php bloginfo('url'); ? ... 
- Windows服务操作帮助类
			/// <summary> /// 打开系统服务 /// </summary> /// <param name="serviceName">系统 ... 
- Nginx基本使用方法
			原帖:http://zyjustin9.iteye.com/blog/2017394 相信很多人都听过nginx,这个小巧的东西慢慢地在吞食apache和IIS的份额.那究竟它有什么作用呢?可能很多人 ... 
- for i in range()
			for i in range()就是python中的循环语句 有以下三种常见用法: 1.range(3) [0,3)即0,1,2 2.range(1,3) [1,3)即1,2 3.range(1,5, ... 
- JS的BOM操作语法
			整理了一下JS的BOM操作语法,这里记录一下. <!DOCTYPE html> <html> <head> <meta charset="utf-8 ... 
- 1、4 前后端分离,写静态HTML文件,通过ajax 返回数据
			1.html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <ti ... 
