Python的继承是多继承机制,一个子类可以同时有多个直接父类;继承可以得到父类定义的方法,子类就可以复用父类的方法。

一、继承的语法

子类:实现继承的类。

父类(基类、超类):被继承的类。

子类继承父类是在定义子类时,将多个父类放在子类之后的圆括号内,如果定义类时,未指定这个类的直接父类,则默认继承object类,所以object类是所有类的父类(直接父类或者是间接父类)。

语法格式如下:

class SubClass (SuperClassl , SuperClass2 , ... ):
# 类定义部分

使用例子:

class Animal:
def dog(self):
print ('我有一只狗!他叫%s'%self.dog_name) class Child:
def son(self):
print ('我有两个儿子!') # 定义Myself类,继承Animal类和Child类
class Myself(Animal,Child):
def name(self):
print ('我叫小明!') M = Myself() # 创建Myself对象
M.dog_name = '大黄' # 通过Myself对象添加dog_name类变量
M.dog() # 调用Myself对象的dog()方法,打印 我有一只狗!他叫大黄
M.son() # 调用Myself对象的son()方法,打印 我有两个儿子!
M.name() # 调用Myself对象的name()方法,打印 我叫小明!

在上面的例子中,定义了Animal和Child两个父类,和一个继承Animal类和Child类的Myself类;创建Myself对象后,可以访问Myself对象的dog()方法和son()方法,说明Myself对象也具有dog()方法和son()方法,所以继承可以得到父类定义的方法,通过继承子类就可以复用父类的方法。

二、多继承

子类会通过继承得到所有父类的方法,那么如果多个父类中有相同的方法名,排在前面的父类同名方法会“遮蔽”排在后面的父类同名方法,例:

class Animal:
def name(self):
print ('我有一只狗,他叫大黄!') class Child:
def name(self):
print ('我有两个儿子!') class Myself(Animal,Child):
pass class Yourself(Child,Animal):
pass M = Myself()
M.name() # 打印 我有一只狗,他叫大黄!
Y = Yourself()
Y.name() # 打印 我有两个儿子!

上面例子中,Myself类继承了Animal类和Child类,当Myself子类对象调用name()方法时,因为Myself子类中没有定义name()方法,Python会先在Animal父类中搜寻name()方法,一旦搜寻到就会停止继续向下搜寻,所以运行的是Animal类中的name()方法;而Yourself子类中由于Child父类排在前面,所以运行的是Child类的name()方法。

三、重写

子类包含与父类同名的方法称为方法重写(方法覆盖),可以说是重写父类方法,也可以说子类覆盖父类方法。

例:

class Animal:
def name(self):
print ('我有一只狗,他叫大黄!') class Myself(Animal):
# 重写Animal类的name()方法
def name(self):
print ('我没有狗,我只有一只猫,他叫大白!') M = Myself() # 创建Myself对象
M.name() # 执行Myself对象的name()方法,打印 我没有狗,我只有一只猫,他叫大白!

上面的例子中,运行M.name()时执行的不再是Animal类的fly()方法,而是Myself类的name()方法。

在子类中重写方法之后,如果需要用到父类中被重写的实例方法,可以通过类名调用实例方法来调用父类被重写的方法。

例:

class Animal:
def name(self):
print ('我有一只狗,他叫大黄!') class Myself(Animal):
# 重写Animal类的name()方法
def name(self):
print ('我还有一只猫,他叫大白!') def pet(self):
Animal.name(self) # 调用被重写的父类方法name(),使用类名.实例名调用,需要手动传self
self.name() # 执行name()方法,会调用子类重写的name()方法 M = Myself() # 创建Myself对象
M.pet()
'''
打印
我有一只狗,他叫大黄!
我还有一只猫,他叫大白!
'''

  

四、super函数调用父类构造方法

如果子类有多个直接的父类,那么排在前面的构造方法会遮蔽排在后面的构造方法。

例:

class Animal:
def __init__(self,pet,name):
self.pet = pet
self.name = name def favourite_animal(self):
print ('我有一只%s,他叫%s!'%(self.pet,self.name)) class Fruit:
def __init__(self,kind):
self.kind = kind def favourite_fruit(self):
print ('我喜欢的水果是%s!'%self.kind) class Myself(Animal,Fruit):
pass M = Myself('狗','大黄') # 创建Myself对象
M.favourite_animal() # 调用Myself对象的favourite_animal()方法,打印 我有一只狗,他叫大黄!
M.favourite_fruit() # 调用Myself对象的favourite_fruit方法,由于未初始化Fruit对象的kind实例变量,报错 AttributeError: 'Myself' object has no attribute 'kind'

上面例子中,Myself子类继承了Animal父类和Fruit父类,由于Animal父类排在Fruit父类前面,所以Animal父类的构造函数遮蔽了Fruit父类的构造函数,运行M.favourite_animal()没有任何问题,当运行M.favourite_fruit()时,由于未初始化Fruit对象的kind实例变量,所以程序会报错。

解决以上问题,Myself应该重写父类的构造方法,子类的构造方法可以调用父类的构造方法,有以下两种方式:

1.使用未绑定方法,即: 父类名.__init__(self,参数1,参数2....)。

2.使用super()函数调用父类构造方法。

先查看一下super()函数的帮助信息,

>>> help(super)
Help on class super in module builtins: class super(object)
| super() -> same as super(__class__, <first argument>)
| super(type) -> unbound super object
| super(type, obj) -> bound super object; requires isinstance(obj, type)
| super(type, type2) -> bound super object; requires issubclass(type2, type)
| Typical use to call a cooperative superclass method:
| class C(B):
| def meth(self, arg):
| super().meth(arg)
| This works for class methods too:
| class C(B):
| @classmethod
| def cmeth(cls, arg):
| super().cmeth(arg)
...

通过帮助信息,可以看到,当调用父类的实例方法时,会自动绑定第一个参数self;当调用类方法时,会自动绑定第一个参数cls。

接下来修改上面的程序:

class Animal:
def __init__(self,pet,name):
self.pet = pet
self.name = name def favourite_animal(self):
print ('我有一只%s,他叫%s!'%(self.pet,self.name)) class Fruit:
def __init__(self,kind):
self.kind = kind def favourite_fruit(self):
print ('我喜欢的水果是%s!'%self.kind) class Myself(Animal,Fruit):
def __init__(self,pet,name,kind):
Fruit.__init__(self,kind) # 通过未绑定方法调用父类构造方法
super().__init__(pet,name) # 通过super()函数调用父类构造方法 M = Myself('狗','大黄','苹果')
M.favourite_animal() # 打印 我有一只狗,他叫大黄!
M.favourite_fruit() # 打印 我喜欢的水果是苹果!

  

Python——继承的更多相关文章

  1. python 继承中的super

    python继承中子类访问父类的方法(包括__init__)主要有两种方法,一种是调用父类的未绑定方法,另一种是使用super(仅仅对于新式类),看下面的两个例子: #coding:utf-8 cla ...

  2. python继承

    Python继承 继承实例: 父类和子类的关系: 继承树: 没有父类就继承object类,不要忘记调用super().__init__来初始化父类 代码: class Person(object): ...

  3. python继承——封装

    python继承--封装 1 为什么要封装 封装数据的主要原因是:保护隐私 封装方法的主要原因是:隔离复杂度 2 封装分为两个层面 第一个层面的封装(什么都不用做):创建类和对象会分别创建二者的名称空 ...

  4. python 继承与多重继承

    当然,如果不支持python继承,语言特性就不值得称为“类”.派生类定义的语法如下所示: <statement-1> . . . <statement-N> 名称 BaseCl ...

  5. python 继承和多态

    在OOP程序设计中,当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类.父类或超类(Base class.Supe ...

  6. python继承的实例

    class SchoolMember(object):#定义学校 member=0#默认成员为0个 amount=0#默认学费为0元 def __init__(self,name,age,sex):# ...

  7. python 继承基础

    class annamal: def chi(self): print(self.name + '吃') def he(self): print(self.name + '喝') class dog( ...

  8. Python继承扩展内置类

    继承最有趣的应用是给内置类添加功能,在之前的Contact类中,我们将联系人添加到所有联系人的列表里,如果想通过名字来搜索,那么就可以在Contact类添加一个方法用于搜索,但是这种方法实际上属于列表 ...

  9. Python继承、方法重写

    继承 在编写类时,并不是每次都要从空白开始.当要编写的类和另一个已经存在的类之间存在一定的继承关系时,就可以通过继承来达到代码重用的目的,提高开发效率. class one(): "&quo ...

  10. python继承和多态

    继承 目标 单继承 多继承 面向对象三大特性 封装 根据 职责 将 属性 和 方法 封装 到一个抽象的 类 中 继承 实现代码的重用,相同的代码不需要重复的编写 多态 不同的对象调用相同的方法,产生不 ...

随机推荐

  1. SpringBoot配置虚拟化路径用于图片的展示

    前言:springboot默认可以访问resources下的static文件夹下的静态资源,我们一般将图片指定上传到static下的某个文件夹,例如images,开发阶段可以使用,但是当项目打成jar ...

  2. 4 个用于执行高级数学计算的 JavaScript 库

    在使用JavaScript执行数学方面的任务时,往往要用到浮点运算,且需要精确到某位小数,这就容易造成错误,而且会相当费时.因此,如果你需要做一些高精度的数学计算的编程工作,比如财务或科学计算,那么你 ...

  3. Phpstudy 无法启动mysql

    原因: 两个mysql版本冲突 本地已经有一个mysql服务(3306)默认开启,再装了phpstudy又会自带一个mysqlla服务(3306) phpstudy启动后会启动mysqlla  发现3 ...

  4. 当fixed元素相互嵌套时,父元素会影响子元素的层叠关系,最好不要嵌套使用fixed

    问题:fixed元素被另一个fixed元素包含的时候在chrome下fixed子元素的定位会受到父元素的影响. 解释:层叠关系是受层叠上下文影响的.文档中的层叠上下文由满足以下任意一个条件的元素形成: ...

  5. F5健康检查导致的服务端连接异常RST

    1. TCP健康检查 比如阿里云,F5负载设备当前都有这种机制. 该实现机制可能会导致后端ECS认为相关TCP连接出现异常(非正常退出),并在业务软件如Java连接池等日志中抛出相应的错误信息,如Co ...

  6. Docker Rootless Container

    容器安全拾遗 - Rootless Container初探-云栖社区-阿里云https://yq.aliyun.com/articles/700923 medium.comhttps://medium ...

  7. 使用cmi工具连接服务器远程装机exsi

    使用cmi工具连接服务器远程装机exsi 网宿机房有两台服务器磁盘坏掉了,后面换了磁盘需要重新初始化系统 访问:http://192.168.48.133/cgi/url_redirect.cgi?u ...

  8. .NET Core入门程序

    易百教程 https://www.yiibai.com/dotnet_core/dotnet_core_getting_started.html

  9. 安卓 android studio 报错 Could not find com.android.tools.build:gradle:3.2.1.

    报错截图如下: 解决方法:在project的builde.gradle做如下操作分别加上google()

  10. Apache调优(二)

    Apache调优(一) (1).Apache运行模式说明 Apache目前一共有三种稳定的MPM(Multi-Processing Module,多进程处理模块)模式:Prefork(进程模式).Wo ...