继承

  继承(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. POJ 1035-Spell checker(字符串)

    题目地址:POJ 1035 题意:输入一部字典.输入若干单词. 若某个单词能在字典中找到,则输出corret.若某个单词能通过 变换 或 删除 或 加入一个字符后.在字典中找得到.则输出这些单词.输出 ...

  2. 书剑恩仇录online全套源代码(服务端+client+文档)

    书剑恩仇录online全套源代码(服务端+client+文档).vc++开发,解压后将近10G大小,眼下网上最完整版本号,包括client源代码.服务端源代码.工具源代码.sdk.文档-- <书 ...

  3. CSS 相对/绝对(relative/absolute)定位与jQuery的控制显示隐藏

    曾经写显示隐藏老是用jq方法控制: dom.show(); dom.hide(); 事实上这样还是有非常多缺陷的. 这是html结构: <div class="holi"&g ...

  4. NuGet配置代理

    https://stackoverflow.com/questions/9232160/nuget-behind-proxy nuget.exe config -set http_proxy=http ...

  5. 暑假集训-WHUST 2015 Summer Contest #0.2

    ID Origin Title 10 / 55 Problem A Gym 100625A Administrative Difficulties   4 / 6 Problem B Gym 1006 ...

  6. 洛谷P1919 【模板】A*B Problem升级版(FFT快速傅里叶)

    题目描述 给出两个n位10进制整数x和y,你需要计算x*y. 输入输出格式 输入格式: 第一行一个正整数n. 第二行描述一个位数为n的正整数x. 第三行描述一个位数为n的正整数y. 输出格式: 输出一 ...

  7. Vue常见面试题汇总

    Vue框架常见面试题   1.active-class是哪个组件的属性?嵌套路由怎么定义? 答:vue-router模块的router-link组件. 2.怎么定义vue-router的动态路由?怎么 ...

  8. 学习NLP:《精通Python自然语言处理》中文PDF+英文PDF+代码

    自然语言处理是计算语言学和人工智能之中与人机交互相关的领域之一. 推荐学习自然语言处理的一本综合学习指南<精通Python自然语言处理>,介绍了如何用Python实现各种NLP任务,以帮助 ...

  9. OpenJDK源码研究笔记(十五):吐槽JDK中的10个富有争议的设计

    前14篇文章,分享了JDK中值得学习和借鉴的编码和设计方法. 每个硬币都是有两面的.Every coin has two sides. 当然,JDK中也有很多值得改进或者说富有争议的设计. 本篇,就来 ...

  10. AutoLayout具体解释+手把手实战

    首先说一下这篇博客尽管是标记为原创,可是事实并不是本人亲自写出来的.知识点和样例本人花了一天各处查找和整理终于决定写一个汇总的具体解释,解去各位朋友到处盲目查找的必要,由于不是转载某一个人的内容.故此 ...