继承

什么是继承

继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类

python中类的继承分为:单继承和多继承

  1. class ParentClass1: #定义父类
  2. pass
  3.  
  4. class ParentClass2: #定义父类
  5. pass
  6.  
  7. class SubClass1(ParentClass1): #单继承,基类是ParentClass1,派生类是SubClass
  8. pass
  9.  
  10. class SubClass2(ParentClass1,ParentClass2): #python支持多继承,用逗号分隔开多个继承的类
  11. pass

查看继承

  1. >>> SubClass1.__bases__ #__base__只查看从左到右继承的第一个子类,__bases__则是查看所有继承的父类
  2. (<class '__main__.ParentClass1'>,)
  3. >>> SubClass2.__bases__
  4. (<class '__main__.ParentClass1'>, <class '__main__.ParentClass2'>)

提示:如果没有指定基类,python的类会默认继承object类,object是所有python类的基类,它提供了一些常见方法(如__str__)的实现。

  1. >>> ParentClass1.__bases__
  2. (<class 'object'>,)
  3. >>> ParentClass2.__bases__
  4. (<class 'object'>,)

继承与抽象(先抽象再继承)

抽象即抽取类似或者说比较像的部分。

抽象分成两个层次:

1.将奥巴马和梅西这俩对象比较像的部分抽取成类;

2.将人,猪,狗这三个类比较像的部分抽取成父类。

抽象最主要的作用是划分类别(可以隔离关注点,降低复杂度)

继承:是基于抽象的结果,通过编程语言去实现它,肯定是先经历抽象这个过程,才能通过继承的方式去表达出抽象的结构。

抽象只是分析和设计的过程中,一个动作或者说一种技巧,通过抽象可以得到类

继承与重用性

  1. ==========================第一部分
  2. 例如
  3.  
  4.   猫可以:喵喵叫、吃、喝、拉、撒
  5.  
  6.   狗可以:汪汪叫、吃、喝、拉、撒
  7.  
  8. 如果我们要分别为猫和狗创建一个类,那么就需要为 实现他们所有的功能,伪代码如下:
  9.  
  10. #猫和狗有大量相同的内容
  11. class 猫:
  12.  
  13. def 喵喵叫(self):
  14. print '喵喵叫'
  15.  
  16. def 吃(self):
  17. # do something
  18.  
  19. def 喝(self):
  20. # do something
  21.  
  22. def 拉(self):
  23. # do something
  24.  
  25. def 撒(self):
  26. # do something
  27.  
  28. class 狗:
  29.  
  30. def 汪汪叫(self):
  31. print '汪汪叫'
  32.  
  33. def 吃(self):
  34. # do something
  35.  
  36. def 喝(self):
  37. # do something
  38.  
  39. def 拉(self):
  40. # do something
  41.  
  42. def 撒(self):
  43. # do something
  44.  
  45. ==========================第二部分
  46. 上述代码不难看出,吃、喝、拉、撒是猫和狗都具有的功能,而我们却分别的猫和狗的类中编写了两次。如果使用 继承 的思想,如下实现:
  47.  
  48.   动物:吃、喝、拉、撒
  49.  
  50.    猫:喵喵叫(猫继承动物的功能)
  51.  
  52.    狗:汪汪叫(狗继承动物的功能)
  53.  
  54. 伪代码如下:
  55. class 动物:
  56.  
  57. def 吃(self):
  58. # do something
  59.  
  60. def 喝(self):
  61. # do something
  62.  
  63. def 拉(self):
  64. # do something
  65.  
  66. def 撒(self):
  67. # do something
  68.  
  69. # 在类后面括号中写入另外一个类名,表示当前类继承另外一个类
  70. class 猫(动物):
  71.  
  72. def 喵喵叫(self):
  73. print '喵喵叫'
  74.  
  75. # 在类后面括号中写入另外一个类名,表示当前类继承另外一个类
  76. class 狗(动物):
  77.  
  78. def 汪汪叫(self):
  79. print '汪汪叫'
  80.  
  81. ==========================第三部分
  82. #继承的代码实现
  83. class Animal:
  84.  
  85. def eat(self):
  86. print("%s 吃 " %self.name)
  87.  
  88. def drink(self):
  89. print ("%s 喝 " %self.name)
  90.  
  91. def shit(self):
  92. print ("%s 拉 " %self.name)
  93.  
  94. def pee(self):
  95. print ("%s 撒 " %self.name)
  96.  
  97. class Cat(Animal):
  98.  
  99. def __init__(self, name):
  100. self.name = name
  101. self.breed = '猫'
  102.  
  103. def cry(self):
  104. print('喵喵叫')
  105.  
  106. class Dog(Animal):
  107.  
  108. def __init__(self, name):
  109. self.name = name
  110. self.breed='狗'
  111.  
  112. def cry(self):
  113. print('汪汪叫')
  114.  
  115. # ######### 执行 #########
  116.  
  117. c1 = Cat('小白家的小黑猫')
  118. c1.eat()
  119.  
  120. c2 = Cat('小黑的小白猫')
  121. c2.drink()
  122.  
  123. d1 = Dog('胖子家的小瘦狗')
  124. d1.eat()
  125.  
  126. 使用继承来重用代码比较好的例子
  127.  
  128. 使用继承来解决代码重用的例子

使用继承来解决代码重用的例子

在开发程序的过程中,如果我们定义了一个类A,然后又想新建立另外一个类B,但是类B的大部分内容与类A的相同时

我们不可能从头开始写一个类B,这就用到了类的继承的概念。

通过继承的方式新建类B,让B继承A,B会‘遗传’A的所有属性(数据属性和函数属性),实现代码重用

  1. class Animal:
  2. '''
  3. 人和狗都是动物,所以创造一个Animal基类
  4. '''
  5. def __init__(self, name, aggressivity, life_value):
  6. self.name = name # 人和狗都有自己的昵称;
  7. self.aggressivity = aggressivity # 人和狗都有自己的攻击力;
  8. self.life_value = life_value # 人和狗都有自己的生命值;
  9.  
  10. def eat(self):
  11. print('%s is eating'%self.name)
  12.  
  13. class Dog(Animal):
  14. pass
  15.  
  16. class Person(Animal):
  17. pass
  18.  
  19. egg = Person('egon',10,1000)
  20. ha2 = Dog('二愣子',50,1000)
  21. egg.eat()
  22. ha2.eat()

提示:用已经有的类建立一个新的类,这样就重用了已经有的软件中的一部分设置大部分,大大生了编程工作量,这就是常说的软件重用,不仅可以重用自己的类,也可以继承别人的,比如标准库,来定制新的数据类型,这样就是大大缩短了软件开发周期,对大型软件开发来说,意义重大.

派生

当然子类也可以添加自己新的属性或者在自己这里重新定义这些属性(不会影响到父类),需要注意的是,一旦重新定义了自己的属性且与父类重名,那么调用新增的属性时,就以自己为准了。

  1. class Animal:
  2. '''
  3. 人和狗都是动物,所以创造一个Animal基类
  4. '''
  5. def __init__(self, name, aggressivity, life_value):
  6. self.name = name # 人和狗都有自己的昵称;
  7. self.aggressivity = aggressivity # 人和狗都有自己的攻击力;
  8. self.life_value = life_value # 人和狗都有自己的生命值;
  9.  
  10. def eat(self):
  11. print('%s is eating'%self.name)
  12.  
  13. class Dog(Animal):
  14. '''
  15. 狗类,继承Animal类
  16. '''
  17. def bite(self, people):
  18. '''
  19. 派生:狗有咬人的技能
  20. :param people:
  21. '''
  22. people.life_value -= self.aggressivity
  23.  
  24. class Person(Animal):
  25. '''
  26. 人类,继承Animal
  27. '''
  28. def attack(self, dog):
  29. '''
  30. 派生:人有攻击的技能
  31. :param dog:
  32. '''
  33. dog.life_value -= self.aggressivity
  34.  
  35. egg = Person('egon',10,1000)
  36. ha2 = Dog('二愣子',50,1000)
  37. print(ha2.life_value)
  38. print(egg.attack(ha2))
  39. print(ha2.life_value)

注意:像ha2.life_value之类的属性引用,会先从实例中找life_value然后去类中找,然后再去父类中找...直到最顶级的父类。

在子类中,新建的重名的函数属性,在编辑函数内功能的时候,有可能需要重用父类中重名的那个函数功能,应该是用调用普通函数的方式,即:类名.func(),此时就与调用普通函数无异了,因此即便是self参数也要为其传值.

在python3中,子类执行父类的方法也可以直接用super方法.

  1. class A:
  2. def hahaha(self):
  3. print('A')
  4.  
  5. class B(A):
  6. def hahaha(self):
  7. super().hahaha()
  8. #super(B,self).hahaha()
  9. #A.hahaha(self)
  10. print('B')
  11.  
  12. a = A()
  13. b = B()
  14. b.hahaha()
  15. super(B,b).hahaha()
  16.  
  17. 帮你了解super

super

  1. class Animal:
  2. '''
  3. 人和狗都是动物,所以创造一个Animal基类
  4. '''
  5. def __init__(self, name, aggressivity, life_value):
  6. self.name = name # 人和狗都有自己的昵称;
  7. self.aggressivity = aggressivity # 人和狗都有自己的攻击力;
  8. self.life_value = life_value # 人和狗都有自己的生命值;
  9.  
  10. def eat(self):
  11. print('%s is eating'%self.name)
  12.  
  13. class Dog(Animal):
  14. '''
  15. 狗类,继承Animal类
  16. '''
  17. def __init__(self,name,breed,aggressivity,life_value):
  18. super().__init__(name, aggressivity, life_value) #执行父类Animal的init方法
  19. self.breed = breed #派生出了新的属性
  20.  
  21. def bite(self, people):
  22. '''
  23. 派生出了新的技能:狗有咬人的技能
  24. :param people:
  25. '''
  26. people.life_value -= self.aggressivity
  27.  
  28. def eat(self):
  29. # Animal.eat(self)
  30. #super().eat()
  31. print('from Dog')
  32.  
  33. class Person(Animal):
  34. '''
  35. 人类,继承Animal
  36. '''
  37. def __init__(self,name,aggressivity, life_value,money):
  38. #Animal.__init__(self, name, aggressivity, life_value)
  39. #super(Person, self).__init__(name, aggressivity, life_value)
  40. super().__init__(name,aggressivity, life_value) #执行父类的init方法
  41. self.money = money #派生出了新的属性
  42.  
  43. def attack(self, dog):
  44. '''
  45. 派生出了新的技能:人有攻击的技能
  46. :param dog:
  47. '''
  48. dog.life_value -= self.aggressivity
  49.  
  50. def eat(self):
  51. #super().eat()
  52. Animal.eat(self)
  53. print('from Person')
  54.  
  55. egg = Person('egon',10,1000,600)
  56. ha2 = Dog('二愣子','哈士奇',10,1000)
  57. print(egg.name)
  58. print(ha2.name)
  59. egg.eat()

通过继承建立了派生类与基类之间的关系,它是一种'是'的关系,比如白马是马,人是动物。

当类之间有很多相同的功能,提取这些共同的功能做成基类,用继承比较好,比如教授是老师

  1. >>> class Teacher:
  2. ... def __init__(self,name,gender):
  3. ... self.name=name
  4. ... self.gender=gender
  5. ... def teach(self):
  6. ... print('teaching')
  7. ...
  8. >>>
  9. >>> class Professor(Teacher):
  10. ... pass
  11. ...
  12. >>> p1=Professor('egon','male')
  13. >>> p1.teach()
  14. teaching

python之路----面向对象的继承特性的更多相关文章

  1. python之路----面向对象的封装特性

    封装 [封装] 隐藏对象的属性和实现细节,仅对外提供公共访问方式. 广义上面向对象的封装 :代码的保护,面向对象的思想本身就是一种只让自己的对象能调用自己类中的方法 狭义上的封装 —— 面向对象的三大 ...

  2. 百万年薪python之路 -- 面向对象之三大特性

    1.面向对象之三大特性 1.1封装 封装:就是把一堆代码和数据,放在一个空间,并且可以使用 对于面向对象的封装来说,其实就是使用构造方法将内容封装到 对象 中,然后通过对象直接或者self间接获取被封 ...

  3. 百万年薪python之路 -- 面向对象之继承

    面向对象之继承 1.什么是面向对象的继承 继承(英语:inheritance)是面向对象软件技术当中的一个概念. 通俗易懂的理解是:子承父业,合法继承家产 专业的理解是:子类可以完全使用父类的方法和属 ...

  4. python之路----面向对象的多态特性

    多态 多态指的是一类事物有多种形态 动物有多种形态:人,狗,猪 import abc class Animal(metaclass=abc.ABCMeta): #同一类事物:动物 @abc.abstr ...

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

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

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

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

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

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

  8. python之路 面向对象基础 XML

    一.面向对象基础 1.类(Class): 用来描述具有相同的属性和方法的对象的集合.它定义了该集合中每个对象所共有的属性和方法.对象是类的实例. 类变量:类变量在整个实例化的对象中是公用的.类变量定义 ...

  9. 【python之路面向对象】初级篇

    概述 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发“更快更好更强...” 面向过程编程最易被初学 ...

随机推荐

  1. HTTP协议的前世今生——各版本HTTP协议对比

    HTTP协议是如今互联网与服务端技术的基石,HTTP协议的演进也从侧面反应了互联网技术的快速发展.这两天在准备一次关于HTTP1.1协议特性的技术分享过程中,顺便了解了下各版本HTTP协议的特点,在这 ...

  2. eclipse 中 大小写切换:ctrl+shift+x 转为大写 ctrl+shift+y 转为小写

    ...............

  3. HDU-2680 Choose the best route 单向边+反向dijkstra

    https://vjudge.net/problem/HDU-2680 题意:以起始点 终点 长度 给出一个图,已知可以从w个起点出发,求从任一起点到同一个终点s的最短路径.注意是单向边.m<1 ...

  4. 静默方式安装10g数据库软件+升级patch+手工建库

    通常我们安装Oracle数据库软件,都是用OUI图形界面来完成的,但有些Unix/Linux系统中并未安装图形系统,也就无法使用图形界面来安装Oracle的产品了,对于这种场景,就只能采用静默方式来安 ...

  5. Python:正则表达式的一些例子

    #匹配电话号码(前面3/4-后面7-8): '\d{3,4}-\d{7,8}' #匹配QQ号(从号码1000开始第一位不能为0): '[1,9][0,9]{4}' #匹配身份证(15位数或者18位,考 ...

  6. array string mysql IN LIKE

    $ids = $_POST['ids']; $str = implode(',',$ids); $str = '('.$str.')'; $db_region->region_del($str) ...

  7. GUID Partition Table (GPT)

    https://en.wikipedia.org/wiki/GUID_Partition_Table https://zh.wikipedia.org/wiki/全局唯一标识分区表 GUID Part ...

  8. IRC and security tools

    login:::   /msg NickServ identify <password>. join:::   /join #metasploit 浏览器: Tor操作系统: Tails加 ...

  9. 洛谷P3368 树状数组2 树状数组+差分

    正解:树状数组+差分 解题报告: 戳我! 不得不说灵巧真滴是越来越弱了...连模板题都要放上来了QAQ 因为今天考试的T3正解要用到树状数组这才惊觉树状数组掌握得太太太太差了...之前一直靠线段树续着 ...

  10. bin/hdfs namenode -format 格式化失败

    确认配置正确前提下,将name目录删除重建,再格式化: hadoop防止将已经存在的集群格式化