本章内容

    一、继承

    二、抽象类

    三、继承的实现原理

=======================================================

一、继承

  

  1. 继承的定义

    继承是一种新建类的方式,新建的类被称为子类,子类会继承父类的属性。

    在Python中支持,一个子类(派生类——可以继承一个或者多个父类(基类或者超类)

    

  2. 为什么要用继承

    继承可以有效减少代码冗余

  3. 如何使用继承

    继承代码示例

# 继承示例
class Father1:
pass class Father2:
pass class Son1(Father1): # Son1继承Father1
pass class Son2(Father1,Father2): # Son2同时继承Father1 & Father2
pass print(Son1.__bases__)
print(Son2.__bases__) print(Father1.__bases__)
print(Father2.__bases__)

    以上代码的结果如下:

(<class '__main__.Father1'>,)                             #Son1继承Father1
(<class '__main__.Father1'>, <class '__main__.Father2'>) #Son2继承Father1,Father2
(<class 'object'>,)   #Python3中有默认父类object
(<class 'object'>,)   #Python3中有默认父类object
# 在python3新建的类,默认都有一个父类(object) 

# 在python2中,默认是没有父类,可以添加(object)为父类

    

    需要注意Python2和Python3中关于类的分类是不一样的:

#Python2中的类:
#
# 1.经典类
# 指的是没有继承默认父类object的类,以及没有继承object类的子类
#
# 2.新式类
# 值得是继承默认父类object以及object类子类的类
#
#
#Python3中的类:
#
# 统一都是新式类

  4. 建立继承关系

    继承是类与类之间的关系,需要寻找这种关系,先进行抽象,然后建立继承

    子类所共有的特征,由父类进行统一配置管理

class SchoolPeople:

    school = 'SH high school'

    def __init__(self,name,age,gender):
self.name = name
self.age = age
self.gender = gender def tell_info(self):
print('School:Name is %s, Age is %s, Gender is %s' %(name,age,gender)) class SchoolStudent(SchoolPeople): #继承SchoolPeople def learn(self):
print('%s is learning' %name) def tell_info(self):
print('I'm student %s, Age is %s, Gender is %s ' %(name,age,gender)) class SchoolTeacher(schoolPeople): #继承SchoolPeople def teach(self):
print('%s is teaching' %name) def tell_info(self):
print('I'm teacher %s, Age is %s, Gender is %s ' %(name,age,gender)) student1 = SchoolStudent('Bob','','Male')
teacher1 = SchoolTeacher('Ajax','','Female') print(student1.__dict__)
print(student1.school)
print(teacher1.__dict__) #子类已经自己定义tell_info()函数,显示格式将按照子类的格式显示,不需要按照父类的格式 student1.tell_info()
teacher1.tell_info()

    请仔细查看如下代码:

class Foo:
def F1(self):
print('Foo.F1') def F2(self):
print('Foo.F2')
self.F1() class Bar(Foo): #继承Foo
def F1(self): #子类中同时也有与父类同名的方法F1
print('Bar.F1') obj = Bar()
obj.F2()
# obj先到父类Foo中找到F2方法运行
# 运行到self.F1()的时候会调用子类Bar自己的F1()方法,而不在调用父类的F1()方法

    以上显示的结果为:

Foo.F2
Bar.F1

  

  5. 子类派生出新的方法中重用父类的功能

   派生,是指子类定义自己新的属性,如果与父类同名,以子类自己的为准

    a. 调用父类方法,指名道姓的使用,请看如下代码

class SchoolPeople:
school = 'oldboy' def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex def tell_info(self):
print("""
===========个人信息==========
姓名:%s
年龄:%s
性别:%s
""" %(self.name,self.age,self.sex)) class SchoolTeacher(SchoolPeople): # 继承SchoolPeople def __init__(self, name, age, sex, level, salary):
# self.name = name
# self.age = age
# self.sex = sex
SchoolPeople.__init__(self,name, age, sex) # 点名指向SchoolPeople self.level = level
self.salary = salary def tell_info(self):
SchoolPeople.tell_info(self) # 点名指向SchoolPeople
print("""
等级:%s
薪资:%s
""" %(self.level,self.salary)) tea1 = SchoolTeacher('Bob', 18, 'male', 9, 50k)
# print(tea1.name, tea1.age, tea1.sex, tea1.level, tea1.salary) tea1.tell_info()

    b. 调用父类方法,使用super()方法

      注意区分Python2和Python3中的super()的格式

      这种方法只能调用父类的方法

class SchoolPeople:
school = 'oldboy' def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex def tell_info(self):
print("""
===========个人信息==========
姓名:%s
年龄:%s
性别:%s
""" %(self.name,self.age,self.sex)) class SchoolTeacher(SchoolPeople): # 继承SchoolPeople def __init__(self, name, age, sex, level, salary):
# self.name = name
# self.age = age
# self.sex = sex
super().__init__(self,name, age, sex) # 使用super()指向父类,Python3的格式
#super(SchoolPeople,self).__init__(self,name, age, sex) Python2的格式
self.level = level
self.salary = salary def tell_info(self):
super().tell_info(self) # 使用super()指向父类,Python3的格式
#super(SchoolPeople,self).tell_info(self) Python2的格式
print("""
等级:%s
薪资:%s
""" %(self.level,self.salary)) tea1 = SchoolTeacher('Bob', 18, 'male', 9, 50k)
# print(tea1.name, tea1.age, tea1.sex, tea1.level, tea1.salary) tea1.tell_info()

二、抽象类

  

  主要使用abc模块,实现归一化,父类有的方法,子类必须有。

  需要在父类的方法头部加上@abc.abstractclassmethod

class File(metaclass=abc.ABCMeta):
@abc.abstractmethod
def read(self): #必须要定义下面的方法,如果没有就不让实例化
pass
@abc.abstractmethod
def write(self):
pass
class Sata(File):
def read(self):
pass
def write(self):
pass
def asb(self):
print('adsf')
Fil=Sata()
Fil.asb()
print(Sata.mro())

三、继承的实现原理

  1、继承顺序:

    经典类:当类是经典类时,多继承情况下,在要查找属性不存在时,会按照深度优先的方式查找下去

    新式类:当类是新式类时,多继承情况下,在要查询属性不存在时,会按照广度优先的方式查找下去

  

  2、方法解析顺序(Method Resolution Order, MRO)

  

    在多重继承中存在不相关的祖先类实现同名方法引起的冲突问题,这种问题称作“菱形问题”。

    Python依靠特定的顺序遍历继承图,这个顺序叫做方法解析顺序。

    如图,左图是类的UML图,右图中的虚线箭头是方法解析顺序:

 

  3、使用属性来查看继承的顺序:

    print(类名.mro())

class A(object):
# def test(self):
# print('from A')
pass class B(A):
# def test(self):
# print('from B')
pass class C(A):
# def test(self):
# print('from C')
pass
class D(B):
# def test(self):
# print('from D')
pass class E(C):
# def test(self):
# print('from E')
pass
class F(D,E):
# def test(self):
# print('from F')
pass f1=F()
print(F.mro())

  4. 处理多重继承的建议

 

  (1)把接口继承和实现继承区分开;

    •   继承接口:创建子类型,是框架的支柱;

    •   继承实现:通过重用避免代码重复,通常可以换用组合和委托模式。

  (2)使用抽象基类显式表示接口;

  (3)通过混入重用代码;
    混入类为多个不相关的子类提供方法实现,便于重用,但不会实例化。并且具体类不能只继承混入类。

  (4)在名称中明确指明混入;
    Python中没有把类声明为混入的正规方式,Luciano推荐在名称中加入Mixin后缀。如Tkinter中的XView应变成XViewMixin。

  (5)抽象基类可以作为混入,反过来则不成立;
    抽象基类与混入的异同:

    •   抽象基类会定义类型,混入做不到;

    •   抽象基类可以作为其他类的唯一基类,混入做不到;

    •   抽象基类实现的具体方法只能与抽象基类及其超类中的方法协作,混入没有这个局限。

  (6)不要子类化多个具体类;
    具体类可以没有,或者至多一个具体超类。
    例如,Class Dish(China,Japan,Tofu)中,如果Tofu是具体类,那么China和Japan必须是抽象基类或混入。

  (7)为用户提供聚合类;
    聚合类是指一个类的结构主要继承自混入,自身没有添加结构或行为。Tkinter采纳了此条建议。

  (8)优先使用对象组合,而不是类继承。
    优先使用组合可以令设计更灵活。

  组合和委托可以代替混入,但不能取代接口继承去定义类型层次结构。

Python入门之面向对象之类继承与派生的更多相关文章

  1. Python 入门 之 面向对象的三大特性(封装 / 继承 / 多态)

    Python 入门 之 面向对象的三大特性(封装 / 继承 / 多态) 1.面向对象的三大特性: (1)继承 ​ 继承是一种创建新类的方式,在Python中,新建的类可以继承一个或多个父类,父类又可以 ...

  2. Python面向对象编程——继承与派生

    Python面向对象编程--继承与派生 一.初始继承 1.什么是继承 继承指的是类与类之间的关系,是一种什么"是"什么的关系,继承的功能之一就是用来解决代码重用问题. 继承是一种创 ...

  3. python语法学习面向对象之继承

    python语法学习面向对象之继承 转载自:http://www.cnblogs.com/Joans/archive/2012/11/09/2757368.html 只要涉及到面向对象,”类“是必须出 ...

  4. 转 python语法学习面向对象之继承

    传送门 python语法学习面向对象之继承 只要涉及到面向对象,”类“是必须出现的一个代名词. 类和对象是面向对象编程的两个主要方面.类创建一个新类型,而对象是这个类的实例. 类的一些概念: 包括初始 ...

  5. Python入门篇-面向对象概述

    Python入门篇-面向对象概述 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.语言的分类 面向机器 抽象成机器指令,机器容易理解 代表:汇编语言 面向过程 做一件事情,排出个 ...

  6. Python入门之面向对象的__init__和__new__方法

    Python入门之面向对象的__init__和__new__方法

  7. python 面向对象之继承与派生

    一:初识继承 1,什么是继承? 继承指的是类与类之间的关系,是一种什么"是"什么的关系,继承的功能之一就是用来解决代码重用问题 继承是一种创建新类的方式,在python中,新建的类 ...

  8. python之旅:面向对象之继承与派生

    一 初识继承 编写类时,并非总要从空白开始.如果你要编写的类正好是另一个现成类的特殊版本,可使用继承来减少代码冗余,子类会“遗传”父类的属性,从而解决代码重用问题 什么是继承 继承是一种创建新类的方式 ...

  9. python面向对象之继承与派生

    一.继承 继承是一种创建新的类的方式,在python中,新建的类可以继承自一个或者多个父类,原始类称为基类或超类,新建的类称为派生类或子类. python中类的继承分为:单继承和多继承,如果是多继承的 ...

随机推荐

  1. 2018/04/03 PHP 中的 进制计算问题

    还是先抛出一个问题 017 + 1 = ? -- 如果你知道的话,那也就不用看下面了,哈哈. 答案是 // 15 -- 如果你想的答案和这个不对的话,说明你也有这个问题,也应该学习一下啦. -- 首先 ...

  2. Ancient Go---hdu5546(dfs爆搜CCPC题目)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5546 题意就是两个人下围棋,问在下一颗x是否能杀死o,'.'是空位子: 枚举所有的点,判断是否合法即可 ...

  3. Elasticsearch教程-从入门到精通(转)

    原文:http://mageedu.blog.51cto.com/4265610/1714522?utm_source=tuicool&utm_medium=referral 各位运维同行朋友 ...

  4. 建立一个更高级别的查询 API:正确使用Django ORM 的方式(转)

    add by zhj: 本文作者是DabApps公司的技术主管,作者认为在view中直接使用Django提供的ORM查询方法是不好的,我对此并不赞同,可能作者 写这篇文章是给Django的初学者看,所 ...

  5. "context:annotation-config" and "context:component-scan"

    1.<context:annotation-config/>注册多个处理器 <context:annotation-config/>作用是向 Spring 容器注册 Autow ...

  6. Python一键安装全部依赖包

    requirements.txt用来记录项目所有的依赖包和版本号,只需要一个简单的pip命令就能完成. pip freeze >requirements.txt 然后就可以用 pip insta ...

  7. vertx打成jar包发布工程,访问静态页面

    1:添加pom依赖,配置打包插件 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="htt ...

  8. POJ1860:Currency Exchange(BF)

    http://poj.org/problem?id=1860 Description Several currency exchange points are working in our city. ...

  9. Bellon(多么痛的领悟)

    尼玛  我今天刚刚知道什么是负权回路 任意相连的无向图之间都是回路!!! 囧了一天了,算是看出来了,渣比 A====B 则A能到B且B能到A,这就是一个回路.

  10. Mr Cao 的提问

    block调用时,变量的生命周期有哪几种?分别是什么样的? 98.CALayer的多个sublaye的数据结构,以及重绘顺序? 99.网路请求的超时及重试机制应该如何设计? 100.NSDiction ...