Python 在子类中调用父类方法详解(单继承、多层继承、多重继承)
Python 在子类中调用父类方法详解(单继承、多层继承、多重继承)
by:授客 QQ:1033553122
测试环境:
win7 64位
Python版本:Python 3.3.5
代码实践:
1、在子类中通过“类名”调用父类的方法
class FatherA:
def __init__(self):
print('init action in father class A')
class SubClassB(FatherA):
def __init__(self):
print('init action in subclass B')
FatherA.__init__(self) # 在子类中调用父类的方法:父类名.方法名称(参数)
if __name__ == '__main__':
b = SubClassB()
运行结果:
>>> ================================ RESTART ================================
>>>
init action in subclass B
init action in father class A
缺点:当一个子类的父类发生变化时(如类SubClassB的父类由FatherA变为FatherD时),必须遍历整个类定义,把子类中所有的父类类名全部替换过来
2、在子类中通过“super”方法调用父类的方法
场景1、单层继承
class FatherA:
def __init__(self):
print('init action in father class A')
class SubClassB(FatherA):
def __init__(self):
print('init action in father class B')
super().__init__() # 在子类中调用父类的方法:super().方法名称(参数)
if __name__ == '__main__':
b = SubClassB()
class FatherA:
def __init__(self):
print('init action in father class A')
class SubClassB(FatherA):
def __init__(self):
print('init action in subclass B')
super(SubClassB, self).__init__() # 在子类中调用父类的方法:super(type, obj).方法名称(参数)
if __name__ == '__main__':
b = SubClassB()
运行结果:
>>> ================================ RESTART ================================
>>>
init action in father class B
init action in father class A
说明:
1、super(type, obj),其中obj必须是type类型、type子类类型的实例,否则会报错:
TypeError: super(type, obj): obj must be an instance or subtype of type
2、super().__init__() 效果等同 super(SubClassB, self). __init__()
场景2、多层继承
实验1:
class FatherA:
def __init__(self):
print('init action in father class A')
class SubClassB(FatherA):
def __init__(self):
print('init action in subclass B')
super().__init__()
class SubClassC(SubClassB):
def __init__(self):
print('init action in subclass C')
super().__init__()
if __name__ == '__main__':
b = SubClassC()
运行结果:
>>> ================================ RESTART ================================
>>>
init action in subclass C
init action in subclass B
init action in father class A
对比实验1-1:
class FatherA:
def __init__(self):
print('init action in father class A')
class SubClassB(FatherA):
def __init__(self):
print('init action in subclass B')
super().__init__()
class SubClassC(SubClassB):
def __init__(self):
print('init action in subclass C')
super(SubClassB, self).__init__()
if __name__ == '__main__':
b = SubClassC()
运行结果:
>>> ================================ RESTART ================================
>>>
init action in subclass C
init action in father class A
>>>
对比实验1-2:
class FatherA:
def __init__(self):
print('init action in father class A')
class SubClassB(FatherA):
def __init__(self):
print('init action in subclass B')
super().__init__()
class SubClassC(SubClassB):
def __init__(self):
print('init action in subclass C')
super(FatherA, FatherA).__init__(self) # 在子类中调用父类的方法:super(type, type).方法名称(参数)
if __name__ == '__main__':
b = SubClassC()
说明:可把 super(FatherA, FatherA).__init__(self) 换成:
super(FatherA, self).__init__()
或
super(FatherA, SubClassB).__init__(self)
或
super(FatherA, SubClassC).__init__(self)
注意:以上这种情况,必须给__init__传递参数self,否则会报错:
TypeError: __init__() missing 1 required positional argument: 'self'
运行结果:
>>> ================================ RESTART ================================
>>>
init action in subclass C
>>>
说明:super(type1, type2) ,type2必须和type1相同类型,或者其子类类型
实验2:
class FatherA:
def __init__(self):
print('init action in father class A')
class SubClassB(FatherA):
def __init__(self):
print('init action in subclass B')
super().__init__()
class SubClassC(SubClassB):
def __init__(self):
print('init action in subclass C')
super().__init__()
class SubClassD(SubClassC):
def __init__(self):
print('init action in subclass D')
super().__init__()
if __name__ == '__main__':
b = SubClassD()
运行结果:
>>> ================================ RESTART ================================
>>>
init action in subclass D
init action in subclass C
init action in subclass B
init action in father class A
对比实验2-1:
class FatherA:
def __init__(self):
print('init action in father class A')
class SubClassB(FatherA):
def __init__(self):
print('init action in subclass B')
super().__init__()
class SubClassC(SubClassB):
def __init__(self):
print('init action in subclass C')
super().__init__()
class SubClassD(SubClassC):
def __init__(self):
print('init action in subclass D')
super(SubClassB, self).__init__()
if __name__ == '__main__':
b = SubClassD()
运行结果:
>>> ================================ RESTART ================================
>>>
init action in subclass D
init action in father class A
>>>
对比实验2-2:
class FatherA:
def __init__(self):
print('init action in father class A')
class SubClassB(FatherA):
def __init__(self):
print('init action in subclass B')
super().__init__()
class SubClassC(SubClassB):
def __init__(self):
print('init action in subclass C')
super().__init__()
class SubClassD(SubClassC):
def __init__(self):
print('init action in subclass D')
super(SubClassC, self).__init__()
if __name__ == '__main__':
b = SubClassD()
运行结果:
>>> ================================ RESTART ================================
>>>
init action in subclass D
init action in subclass B
init action in father class A
通过对比实验2-1, 2-2,可看出super(type[,type2_or_obj]),type决定了super调用方法所在的父类--type的父类(如果有的话),即type决定了前往哪个父类调用指定的方法
场景3、多重继承
实验1:
class FatherA:
def __init__(self):
print('init action in father class A')
class FatherB:
def __init__(self):
print('init action in father class B')
class SubClassC(FatherA, FatherB):
def __init__(self):
print('init action in subclass C')
super(FatherB).__init__()
if __name__ == '__main__':
b = SubClassC()
运行结果:
>>> ================================ RESTART ================================
>>>
init action in subclass C
对比实验1-1:
class FatherA:
def __init__(self):
print('init action in father class A')
class FatherB:
def __init__(self):
print('init action in father class B')
class SubClassC(FatherB, FatherA):
def __init__(self):
print('init action in subclass C')
super().__init__()
if __name__ == '__main__':
b = SubClassC()
运行结果:
>>> ================================ RESTART
================================
>>>
init action in subclass C
init action in father class B
>>>
对比实验1-2:
class FatherA:
def __init__(self):
print('init action in father class A')
class FatherB:
def __init__(self):
print('init action in father class B')
class SubClassC(FatherA, FatherB):
def __init__(self):
print('init action in subclass C')
super().__init__()
if __name__ == '__main__':
b = SubClassC()
运行结果:
>>> ================================ RESTART
================================
>>>
init action in subclass C
init action in father class A
>>>
对比实验1-3:
class FatherA:
def __init__(self):
print('init action in father class A')
class FatherB:
def __init__(self):
print('init action in father class B')
class SubClassC(FatherA, FatherB):
def __init__(self):
print('init action in subclass C')
super(FatherB).__init__()
if __name__ == '__main__':
b = SubClassC()
>>> ================================ RESTART
================================
>>>
init action in subclass C
对比实验1-4:
class FatherA:
def __init__(self):
print('init action in father class A')
def testfn(self, arg):
print('testfn in father class A')
class FatherB:
def __init__(self):
print('init action in father class B')
def testfn(self):
print('testfn in father class B')
class SubClassC(FatherA, FatherB):
def __init__(self):
print('init action in subclass C')
super().testfn()
if __name__ == '__main__':
b = SubClassC()
运行结果:
>>> ================================ RESTART
================================
>>>
init action in subclass C
Traceback (most recent call last):
File
"C:/Users/Administrator/Desktop/1.py", line 21, in
b = SubClassC()
File
"C:/Users/Administrator/Desktop/1.py", line 18, in
__init__
super().testfn()
TypeError: testfn() missing 1 required positional
argument: 'arg'
>>>
对比实验1-5:
class FatherA:
def __init__(self):
print('init action in father class A')
def testfn(self):
print('testfn in father class A')
class FatherB:
def __init__(self):
print('init action in father class B')
def testfn(self, arg):
print('testfn in father class B')
class SubClassC(FatherA, FatherB):
def __init__(self):
print('init action in subclass C')
super().testfn()
if __name__ == '__main__':
b = SubClassC()
运行结果:
>>> ================================ RESTART
================================
>>>
init action in subclass C
testfn in father class A
说明:通过对比实验1-1,1-2,1-3,1-4,1-5可以看出,子类水平方向上,继承多个父类,以super().method(参数)方法调用父类的方法,如果不同父类中存在同名方法method(不管参数列表是否相同),则按继承顺序,选择第一个父类中的方法。,如果想要调用多个方法咋办?如下,通过类名调用
class FatherA:
def __init__(self):
print('init action in father class A')
class FatherB:
def __init__(self):
print('init
action in father class B')
class SubClassC(FatherA, FatherB):
def __init__(self):
print('init action in subclass C')
FatherA.__init__(self)
FatherB.__init__(self)
if __name__ == '__main__':
b = SubClassC()
>>> ================================ RESTART
================================
>>>
init action in subclass C
init action in father class A
init action in father class B
>>>
Python 在子类中调用父类方法详解(单继承、多层继承、多重继承)的更多相关文章
- python基础----继承与派生、组合、接口与归一化设计、抽象类、子类中调用父类方法
一.什么是继承 继承是一种创建新的类的方式,在pyth ...
- python基础之类的继承与派生、组合、接口与归一化设计、抽象类、子类中调用父类方法
一.什么是继承 继承是一种创建新的类的方式,新建的类可以继承自一个或者多个父类,原始类称为基类或超类,新建的类称为派生类或子类. 派生:子类继承了父类的属性,然后衍生出自己新的属性,如果子类衍生出的新 ...
- c++虚函数、子类中调用父类方法
全部 代码: 1 #include<stdio.h> 2 #include<string.h> 3 #include<iostream> 4 #include< ...
- 在子类中调用父类的方法super
1.没有super之前,在子类里面需要父类里面的逻辑,但是我们是通过派生(自己定义了一个init,增加了一条line) class vehichle:#定义一个交通工具的类 Country=" ...
- Python中格式化format()方法详解
Python中格式化format()方法详解 Python中格式化输出字符串使用format()函数, 字符串即类, 可以使用方法; Python是完全面向对象的语言, 任何东西都是对象; 字符串的参 ...
- C++调用JAVA方法详解
C++调用JAVA方法详解 博客分类: 本文主要参考http://tech.ccidnet.com/art/1081/20050413/237901_1.html 上的文章. C++ ...
- Java中的main()方法详解
在Java中,main()方法是Java应用程序的入口方法,也就是说,程序在运行的时候,第一个执行的方法就是main()方法,这个方法和其他的方法有很大的不同,比如方法的名字必须是main,方法必须是 ...
- (转)shell中test命令方法详解
test命令用法.功能:检查文件和比较值 shell中test命令方法详解 原文:https://www.cnblogs.com/guanyf/p/7553940.html 1)判断表达式 if te ...
- 关于 redux-saga 中 take 使用方法详解
本文介绍了关于redux-saga中take使用方法详解,分享给大家,具体如下: 带来一个自己研究好久的API使用方法. redux-saga中effect中take这个API使用方式,用的多的是ca ...
随机推荐
- Yii2+Swagger搭建RESTful风格的API项目
在现有的Advanced Template上搭建RESTful API项目的步骤: 本案例前提说明: 本例中不使用\yii\rest\ActiveController自动创建的API,而是自定义一个A ...
- MySQL高可用架构-MMM安装教程
安装指南: 一.架构以及服务器信息 基本安装包含至少2个数据库服务器和1个监视服务器.本例中使用2个监视服务器和5个数据库服务器(服务器系统为CentOS 7) 用途 IP 主机名 Server-id ...
- ASM路径问题导致数据库不能正常启动 -- 报:ORA-03113: end-of-file on communication channel
环境描述: 操作系统版本:Red Hat Enterprise Linux Server release 6.5 (Santiago) 数据库版本:Oracle 11.2.0.4 RAC 场景描述: ...
- Python标准库 -- UUID模块(生成唯一标识)
UUID是什么: UUID: 通用唯一标识符 ( Universally Unique Identifier ),对于所有的UUID它可以保证在空间和时间上的唯一性,也称为GUID,全称为: UUID ...
- TFS2018环境搭建一单实例安装(适用于小型团队)
1.服务器配置 阿里云 单核CPU,2GB的RAM,SSD硬盘,安装TFS实例 TFS2018要求SQL Server 2016 (minimum SP1)以上.其要求有以下几点: (1).安装SQL ...
- java多线程并发控制countDownLatch和cyclicBarrier的使用
java主线程等待所有子线程执行完毕在执行,这个需求其实我们在工作中经常会用到,比如用户下单一个产品,后台会做一系列的处理,为了提高效率,每个处理都可以用一个线程来执行,所有处理完成了之后才会返回给用 ...
- [原创]Entity Framework查询原理
前言 Entity Framework的全称是ADO.NET Entity Framework,是微软开发的基于ADO.NET的ORM(Object/Relational Mapping)框架.Ent ...
- C++ string中的几个小陷阱,你掉进过吗?
C++开发的项目难免会用到STL的string,使用管理都比char数组(指针)方便的多,但在得心应手的使用过程中也要警惕几个小陷阱,避免我们项目出bug却迟迟找不到原因. 1. 结构体中的stri ...
- 【转】Java中堆和栈的区别
Java的堆是一个运行时数据区,类的对象从中分配空间.这些对象通过new.newarray.anewarray和multianewarray等 指令建立,它们不需要程序代码来显式的释放.堆是由垃圾回收 ...
- Spring总结 1.装配bean
本随笔内容要点如下: 依赖注入 Spring装配bean的方式 条件化装配 一.依赖注入 我理解的依赖注入是这样的:所谓的依赖,就是对象所依赖的其他对象.Spring提供了一个bean容器,它负责创建 ...