继承

  继承(Inheritance)是面向对象的程序设计中代码重要的主要方法。继承是允许使用现有类的功能,并在无需重新改写原来的类的情况下,对这些功能进行扩展。继承可以避免代码复制和相关的代码维护等问题。

  被继承的类称为“基类(Base Class)”、“父类” 或 “超类(Super Class)”,通过继承创建的新类称为“子类(Subclass)” 或 “派生类(Derived Class)”。

  声明格式:

    class 派生类(基类1,[基类2,...]):

      类体

  其中,派生类名后为所有基类的名称元组。如果在类定义中没有指定基类,则默认其基类为objec。object是所有对象的根基类。

  多个类的继承可以形成层次关系,通过类的方法mro()或类的属性__mro__可以输出其继承的层次关系。例如:

class A(object): pass

class B(A): pass

class C(B): pass

class D(A): pass

class E(B, D): pass

print(D.mro())
print(E.__mro__)
------------------line----------------------
[<class '__main__.D'>, <class '__main__.A'>, <class 'object'>] (<class '__main__.E'>, <class '__main__.B'>, <class '__main__.D'>, <class '__main__.A'>, <class 'object'>)

  声明派生类时,必须在其构造函数中调用基类的构造函数。调用格式:

    基类名.__init__(self,参数列表)

  定义一个Car类,再定义一个ElectricCar类,让其继承Car类属性和方法,示例代码:

class Car(object):
def __init__(self, make, model, year):
self.make = make
self.model = model
self.year = year
self.odometer_reading = 0 def get_descriptive_name(self):
long_name = str(self.year) + ' ' + self.make + ' ' + self.model
return long_name.title() def read_odometer(self):
print("This car has " + str(self.odometer_reading) + "miles on it.") def update_odometer(self, mileage):
if mileage >= self.odometer_reading:
self.odometer_reading = mileage
else:
print("You can't roll back an odometer!") def increment_odometer(self, miles):
self.odometer_reading += miles class ElectricCar(Car):
def __init__(self, make, model, year):
Car.__init__(self, make, model, year) my_tesla = ElectricCar('tesla', 'model s', 2016)
print(my_tesla.get_descriptive_name())
------------------line----------------------
2016 Tesla Model S

  这里Car就是ElectricCar的“父类” 或 “超类”, ElectricCar就是Car的“子类” 或 “派生类”。

  代码“Car.__init__(self, make, model, year)”,让Python通过调用Car类中的__init__(),让ElectricCar实例包含父类的所有属性。

  让一个类继承另一个类后,可添加区分子类和父类所需的新属性和方法,为电动汽车添加特有的属性(电瓶)。示例代码:

class Car(object):
-- snip -- class ElectricCar(Car):
def __init__(self, make, model, year):
Car.__init__(self, make, model, year)
self.battery_size = 70 def describe_battery(self):
print("This car has a " + str(self.battery_size) + "-kWH battery.") my_tesla = ElectricCar('tesla', 'model s', 2016)
print(my_tesla.get_descriptive_name())
my_tesla.describe_battery()

------------------line----------------------
2016 Tesla Model S
This car has a 70-kWH battery.

  有的时候父类的一些方法可能不子类的一些特性,我们需要对父类的方法重新构造,我们可在子类中重新定义一个这样的方法,即与要重写的父类的方法同名。假如Car类中有fill_gas_tank()方法,我们在ElectricCar中重构。示例代码:

class ElectricCar(Car):
-- snip -- def fill_gas_tank(self):
print("This car does't need a gas tank!")

  记住,先继承,再重构。

  

  Python支持多重继承,即一个派生类可以继承多个基类。

  多个类的继承可以形成层次关系,通过类的方法mro()或类的属性__mro__可以输出其继承的层次关系。例如:

class A(object): pass

class B(A): pass

class C(B): pass

class D(A): pass

class E(B, D): pass

print(D.mro())
print(E.__mro__)
------------------line----------------------
[<class '__main__.D'>, <class '__main__.A'>, <class 'object'>]
(<class '__main__.E'>, <class '__main__.B'>, <class '__main__.D'>, <class '__main__.A'>, <class 'object'>)

  附1,练习代码:

class SchoolMember(object):
members = 0 def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
self.enroll() def enroll(self):
print("just enrolled a school member [%s] ." % self.name)
SchoolMember.members += 1 def tell(self):
print("------%s info------" % self.name)
for k,v in self.__dict__.items():
print("\t",k,v) def __del__(self):
print("开除了[%s]..." % self.name)
SchoolMember.members += 1 class Teacher(SchoolMember):
def __init__(self, name, age, sex, salary, course):
SchoolMember.__init__(self, name, age, sex)
self.salary = salary
self.course = course def teaching(self):
print("Teacher [%s] is teaching [%s]." % (self.name, self.course)) class Student(SchoolMember):
def __init__(self, name, age, sex, course, tuition):
SchoolMember.__init__(self, name, age, sex)
self.course = course
self.tuition = tuition
self.amount = 0 def pay_tuition(self, amount):
print("Student [%s] has just paied [%s]." % (self.name, amount))
self.amount += amount t1 = Teacher("Alex", 33, "M", 2000, "Python")
s1 = Student("John", 20, "M", "Python", 30000)

  附2,关于新旧类的问题:

  写法1,又称经典类写法:

    基类名.__init__(self,基类中的属性) 

  写法2,又称新式类写法:

    Python 2.7中:

    super(子类名,self).__init__(基类中的属性)

    Python 3.x中:

    super().__init__(基类中的属性)

  注:在Python 2.7中使用继承时,务必在定义父类时在括号内指定object。

  

1.26 Python知识进阶 - 继承的更多相关文章

  1. 1.23 Python知识进阶 - 面向对象编程

    一.编程方法 1.函数式编程:"函数式编程"是一种"编程范式"(programming paradigm),也就是如何编写程序的方法论.它属于"结构化 ...

  2. 1.25 Python知识进阶 - 封装

    封装 示例代码: class Role(object): count = 0 def __init__(self,name,role,weapon,life_value=100,money=15000 ...

  3. 1.24 Python知识进阶 - 类与对象

    类 语法格式: class Dog(object): print("the dog is barking ...") Dog为类名,object为要继承的基类,Dog类会从基类ob ...

  4. Python进阶-继承中的MRO与super

    Python进阶-继承中的MRO与super 写在前面 如非特别说明,下文均基于Python3 摘要 本文讲述Python继承关系中如何通过super()调用"父类"方法,supe ...

  5. Python类的继承(进阶5)

    转载请标明出处: http://www.cnblogs.com/why168888/p/6411918.html 本文出自:[Edwin博客园] Python类的继承(进阶5) 1. python中什 ...

  6. 第4章 基础知识进阶 第4.1节 Python基础概念之迭代、可迭代对象、迭代器

    第四章 基础知识进阶第十七节 迭代.可迭代对象.迭代器 一.    引言 本来计划讲完元组和字典后就讲列表解析和字典解析,但要理解列表解析和字典解析,就需要掌握Python的高级的类型迭代器,因此本节 ...

  7. Python爬虫进阶五之多线程的用法

    前言 我们之前写的爬虫都是单个线程的?这怎么够?一旦一个地方卡到不动了,那不就永远等待下去了?为此我们可以使用多线程或者多进程来处理. 首先声明一点! 多线程和多进程是不一样的!一个是 thread ...

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

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

  9. 二十二. Python基础(22)--继承

    二十二. Python基础(22)--继承 ● 知识框架   ● 继承关系中self的指向 当一个对象调用一个方法时,这个方法的self形参会指向这个对象 class A:     def get(s ...

随机推荐

  1. C语言函数--E

    函数名: ecvt 功 能: 把一个浮点数转换为字符串 用 法: char ecvt(double value, int ndigit, int *decpt, int *sign); 程序例: #i ...

  2. 移动App架构设计

    移动App架构设计 本文主要总结了几种经常使用的架构模式, 基本是层层递进的转载请注名出处 http://blog.csdn.net/uxyheaven, 良好的排版在https://github.c ...

  3. Hadoop HDFS (4) Hadoop Archives

    用HDFS存储小文件是不经济的,由于每一个文件都存在一个block里,每一个block的metadata又在namenode的内存里存着,所以,大量的小文件.会吃掉大量的namenode的内存.(注意 ...

  4. Cordic 算法入门

    三角函数的计算是个复杂的主题,有计算机之前,人们通常通过查找三角函数表来计算任意角度的三角函数的值.这种表格在人们刚刚产生三角函数的概念的时候就已经有了,它们通常是通过从已知值(比如sin(π/2)= ...

  5. [BZOJ4826][HNOI2017]影魔 可持久化线段树

    链接 题意:给你 \(1\) 到 \(n\) 的排列 \(k_1,k_2,\dots,k_n\) ,对 \(i,j (i<j)\)来说,若不存在 \(k_s (i<s<j)\) 大于 ...

  6. spring security oauth2 架构---官方

    原文地址:https://projects.spring.io/spring-security-oauth/docs/oauth2.html Introduction This is the user ...

  7. UltraEdit Companion Utility

    UltraEdit Companion Utility 配色组件 http://www.danielwmoore.com/extras/index.php?action=downloads;sa=vi ...

  8. 基于SIFT的点云关键点提取

    这篇博文主要介绍SIFT算法在提取点云图像关键点时的具体用法. 尺度不变特征转换(Scale-invariant feature transform,SIFT)是David Lowe在1999年发表, ...

  9. 今日SGU 5.13

    SGU 146 题意:就是给你一个长度为l的圈,然后你跑步,每一段给你时间t和速度v,问你最后离起点多远 收获:就是把浮点数转为整数,然后但是会出现精度误差,比如l最多四位小数,那你就加0.00001 ...

  10. powershell《语音报警系统》

    用powershell实现:“倩女幽魂姥姥”版<语音报警系统> ------[第一章 前言]------ win7,及以上版本中,是自带语音库的,系统自带一套女声中文库,一套女声英文库.用 ...