继承

  继承(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. hbase源码系列(十二)Get、Scan在服务端是如何处理

    hbase源码系列(十二)Get.Scan在服务端是如何处理?   继上一篇讲了Put和Delete之后,这一篇我们讲Get和Scan, 因为我发现这两个操作几乎是一样的过程,就像之前的Put和Del ...

  2. hdoj2066一个人的旅行

    Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission ...

  3. css footer not displaying at the bottom of the page

    https://stackoverflow.com/questions/15960290/css-footer-not-displaying-at-the-bottom-of-the-page The ...

  4. git commit template

    https://www.zhihu.com/question/27462267/answer/204658544 https://gist.github.com/adeekshith/cd4c95a0 ...

  5. 同一台服务器部署多个WEB应用,SESSION冲突的解决方法

    由于一台服务器上使用Tomcat部署多个WEB项目,而项目因为用到框架都是一样的,导致同时运行,session相互冲突,这个登录后,那个就得重新登录,造成了使用不方便,解决办法如下: 在server. ...

  6. C#泛型链表Demo

    /// <summary> /// 节点 /// </summary> /// <typeparam name="T"></typepar ...

  7. 外连接OUTER JOIN(三十五)

    外连接OUTER JOIN   LEFT [OUTER] JOIN,左外连接 显示左表的全部记录及右表符合连接条件的记录 下面我们来演示一下,操作命令及部分结果如下: SELECT goods_id, ...

  8. "中国制造2025"+"互联网+",引领制造业发展

    "中国制造2025"+"互联网+",引领制造业发展

  9. 在Ubuntu14.04中配置mysql远程连接教程

    上一篇文章,小编带大家学会了在Ubuntu14.04中安装MySQL,没有来得及上课的小伙伴们可以戳这篇文章:如何在Ubuntu14.04中安装mysql,今天给大家分享一下,如何简单的配置MySQL ...

  10. babel的插件

    比如想编译es6的箭头函数,需要使用babel-plugin-transform-es2015-arrow-functions这个插件 此外babel提供了 prests(预设) 相当于是插件的集合 ...