python类继承中构造方法_第8.3节 Python类的__init__方法深入剖析:构造方法与继承详解...

第8.3节Python类的__init__方法深入剖析:构造方法与继承详解

一、    引言

上两节介绍了构造方法的语法及参数,说明了构造方法是Python的类创建实例后首先执行的方法,并说明如果类没有重写构造方法,Python将会给出默认的__init__方法。上述介绍适用于自定义类没有自定义父类的情况,如果自定义类是从其他自定义类派生的,又会怎样呢?

二、    构造方法与继承

为了保障相关逻辑的正确性,在子类重写构造方法时,必须调用超类(继承的类)的构造方法,否则可能无法正确地初始化对象。

1.    子类在构造方法处理时,可以有两种方法:

1>    继承后不重写构造方法,此时子类直接继承了父类的构造方法;

2>    重写父类构造方法,在子类的构造方法里显式地调用父类的构造方法,对调用执行的具体代码位置没有要求,可以在子类构造方法的开始部分、中间部分或结尾部分都可以,主要看业务逻辑有没有要求。

这两种方法都可以确保子类继承父类时构造方法的正确性。

2.    子类里显示调用父类的构造方法的三种实现方式

1>    父类名.父类构造方法,这种方法需要注意,self参数必须传给父类方法;

2>    super().父类构造方法,这种方法调用不需要也不能传递self参数,由Python自动传入;

3>    super(子类名,self).父类构造方法,这种方法调用也不需要传递self参数。

以上三种方法,老猿推荐大家使用第二种,一是使用简单,不需要给出父类名或子类名,也不需要self参数传递,二是程序修改简单,如果父类或子类名修改无需修改相关代码。不过这种方法只有Python3以后才支持。

三、    案例

1.    案例说明:

本节使用一个继承案例,超类为Vehicle(车),子类为car(小汽车),车只有3个实例变量:wheelcount(轮子数)、power(动力)、行驶总里程totaldistance,子类根据情况不同会有不同的实例变量,最多增加一个实例变量每公里油耗oilcostperkm(使用时错误,后面赋值时是按百公里油耗赋值的,特此说明)。为了聚焦问题,在类内都只定义构造方法,超类的类定义如下:

class Vehicle():

def __init__(self,wheelcount, power):

self.wheelcount,self.power,self.totaldistance = wheelcount,power,0

2.    案例1:子类不重写构造方法

1)    子类定义如下:

class Car(Vehicle):pass

此时应该继承父类的构造方法。

2)    没有写构造方法,不带参数执行实例定义,系统应报错

car=Car()

3)    按父类要求定义实例

car=Car(4,'汽油发动机') #带正确参数执行

4)    案例截图:

25f87cbfad359d2a748cd6914bf04956.png

5)    案例总结:

子类继承父类构造方法,执行实例定义时直接执行该构造方法。

3.    案例2:子类重写构造方法但子类构造方法中不调用父类构造方法

1)    子类定义如下:

class Car(Vehicle):  #子类重写构造方法但子类构造方法中不调用父类构造方法

def __init__(self,wheelcount, power,oilcostperkm):

self.oilcostperkm = oilcostperkm

print("In Car __init__:oilcostperkm=",self.oilcostperkm)。

2)    定义实例

car=Car(4,'汽油发动机',10)

3)    查看实例数据

car.__dict__ #查看实例自定义属性,应该只有oilcostperkm

car.wheelcount #查看实例的    wheelcount,应报错

4)    案例截图:

c083fb73291ab8a543be5f7a77f5c95a.png

5)    案例总结:

子类重写构造方法,如果没有显示调用父类构造方法,则不会执行父类构造方法的相关代码。

4.    案例3:子类重写构造方法并调用父类构造方法

1)    子类定义如下:

class Car(Vehicle):  #子类重写构造方法但子类构造方法中不调用父类构造方法

def __init__(self,wheelcount, power,oilcostperkm):

self.oilcostperkm = oilcostperkm

print("In Car __init__:oilcostperkm=",self.oilcostperkm)

super().__init__(wheelcount, power)

调用父类的构造方法,本例中用的这是一种老猿推荐的调用方法,还可以有下面两种调用方法:

Vehicle.__init__(self,wheelcount, power)

super(Car,self).__init__(wheelcount, power)

2)    定义实例和查看数据

car=Car(4,'汽油发动机',10) #应该执行两个构造方法

car.__dict__ #查看实例自定义属性,应该wheelcount, power,oilcostperkm都有

car.wheelcount #查看实例的    wheelcount,应正常给出

3)    案例截图:

91ec055d9be06f82d07095b265588bf8.png

4)    案例总结:子类重写构造方法,显示调用父类构造方法,相关实例变量都会正常初始化。

本节结合案例详细介绍了在继承情况下应该怎么实现子类的构造方法,内容比较简单但很重要,请大家注意。

老猿Python(https://blog.csdn.net/LaoYuanPython)系列文章用于逐步介绍老猿学习Python后总结的学习经验,这些经验有助于没有接触过Python的程序员可以很容易地进入Python的世界。

欢迎大家批评指正,谢谢大家关注!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/360619.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OpenShift DIY:使用Gradle构建Spring Boot / Undertow应用程序

由于此bug, Gradle 1.6是在OpenShift上运行的最后一个受支持的Gradle版本。 但是从Gradle 2.2开始,这不再是问题,因此使用自己动手做墨盒在OpenShift上运行最新的Gradle不再是问题。 DIY墨盒是一种实验性墨盒,它提供了一种在OpenS…

P2P编程(十)

此为网络编程的一个系列,后续会把内容补上。。。。 转载于:https://www.cnblogs.com/liangjie/p/3155866.html

python默认数据转换_Python_数据类型转换

数据类型转换int(x [,base ]) 将x转换为一个整数long(x [,base ]) 将x转换为一个长整数float(x ) 将x转换到一个浮点数complex(real [,imag ]) 创建一个复数str(x ) 将对象 x 转换为字符串repr(x ) 将对象 x 转换为表达式字符串eval(str ) 用来计算在字符串中的有效Python表达式…

Gradle入门:创建Web应用程序项目

这篇博客文章描述了如何使用Gradle创建一个Web应用程序项目。 更具体地说,我们想创建一个使用Java的Web应用程序项目,将我们的Web应用程序打包到WAR文件中,并在开发环境中运行我们的Web应用程序。 让我们找出如何满足这些要求。 补充阅读&…

js编码java解码_Js编码和Java后台解码

注:在使用get提交,url传递参数的时候,会带来中文乱码的问题,对此可以使用js编码来解决。Js编码的几种方式区别:1.window.escape()与HttpUtility.UrlEncodeUnicode()编码格式一样:将一个汉字编码为%uxxxx格式…

使用JAX-RS和Jetty创建Web服务和Rest Server

用Java创建WebService非常容易。 将其添加到ServletContainer并将其部署到嵌入式WebServer仅需要几行代码。 让我们创建一个具有两个函数的简单计算器,作为WebService的示例。 计算器将计算任何数量的squareRoot和平方。 它将返回一个简单的JSON响应,其…

java填充二维数组_Java用Arrays.fill()初始化二维数组的实现

在最短路径问题上遇到了一个问题,对于二维int数组 map[][],需要初始化为int的最大值,不想用双重循环赋初值,想用Arrays.fill()填充但是失败了。。。。。。首先说明,Arrays.fill()并不能提高赋值的效率,在函数的内部也是…

maya 中使用节点连接来求余数:

绑个东西要用到求余,不喜欢用表达式,就想用节点连出来,找了下网上只有 镀金铆钉 在火星时代上的教程,不过不能下载了,就自己想了下,终于搞出来了,做下笔记,不要忘了。 求余的思路&a…

Java8多线程ForkJoinPool:处理异常

引入Java8 lambda背后的主要动机之一是能够尽可能轻松地使用多核的能力(请参阅精通Lambdas:多核世界中的Java编程 )。 只需将代码从collection.stream()...更改为collection.parallelStream()...您就可以使用即时多线程,从而为您的…

java web 登录界面案例_【JavaWeb】74:写一个登录案例

今天是刘小爱自学Java的第74天。感谢你的观看,谢谢你。话不多说,开始今天的学习:Java又常被称之为后台开发。什么叫后台呢?除了后台还有什么前台、前端后端……这些概念一大堆,还容易弄混。以一个三层架构的知识点来引…

7种JIRA集成可优化Java开发流程

有哪些最佳集成可以用来优化JIRA工作流程? 我喜欢寻找在工作流程中提高效率的方法。 看着那些小的自动化和流畅的流程,使我的脸上露出笑容。 我知道我并不孤单,偶尔花更多的时间来获得一点点提升以使其正常工作,而不是最终节省了我…

hive处理日志,自定义inputformat

开放环境,hadoop-0.20.2,hive-0.6 1.日志分隔符 Xml代码 2010-05-31 10:50:17|||61.132.4.82|||http://www.360buy.com/product/201185.html 2010-05-31 10:50:17|||61.132.4.82|||http://www.360buy.com/product/201185.html分隔符是“ ||| ”&#xf…

java 封箱_java封箱和拆箱分析

学习java肯定会涉及到“封箱”和“拆箱”,那么什么是“封箱”和“拆箱呢?我相信有不少的老师或者作者都对此做过总结,在这里就不详细说了。总的来说就是:装箱就是自动将基本数据类型转换为包装器类型;拆箱就是自动将包…

EE JSP:使用自定义标签库生成动态内容

在Web应用程序中开发View层时,您希望尽量不要重复JSP文件中的内容。 JSP spec API允许您通过使用标记库来减少这种重复。 定制JSP标记是用户定义的xml标记元素,您可以将其插入JSP文件以替换为某些动态内容。 这是一个使用自定义JSP标记的简单jsp示例 &a…

prefuse学习(一)用非数据库连接和xml的方式读入数据

prefuse正常的数据源需要从ConnectionFactory中生产出来,但是如果平时不想用里面给的方法得到数据,就需要手动创造Graph里面所需要的内容两个Table 下面是我自己写的从文件中读入数据的工具类 package wjl.util;import java.io.FileInputStream; import …

java list作为参数传递_Java 程序将lambda表达式作为方法参数传递

Java 程序将lambda表达式作为方法参数传递在此示例中,我们将学习将lambda表达式作为Java中的方法参数传递。要理解此示例,您应该了解以下Java编程主题:示例1:将lambda表达式定义为方法参数示例import java.util.ArrayList;class M…

将ActiveMQ持久消息传递性能提高25倍

Apache ActiveMQ,JBoss A-MQ和Red Hat Apache ActiveMQ是一个非常受欢迎的开源消息传递代理,由创建(和工作) Apache Karaf , Apache Camel , Apache ServiceMix以及许多其他工具的人提供给您。 它拥有一个充…

sql数据库恢复

先附加,然后再备份,然后按如下: --数据还原到指定时间点的处理示例--创建测试数据库CREATE DATABASE DbGO --对数据库进行备份BACKUP DATABASE Db TO DISKc:\db.bak WITH FORMATGO --创建测试表CREATE TABLE Db.dbo.TB_test(ID int) --延时1秒钟,再进行后面的操作(这是由于SQL …

ECMA学习小结(3)——constructor 和 prototype

每个函数都有一个prototype的属性,当我们以这个函数为构造函数创建实例时(即用new的形式),创建出来的这个对象是没有prototype的属性的。以下代码为例:在console里进行调试cf 拥有一个prototype的属性,这个…

java什么是网络接口_java 网络编程 -- IP地址的表示与网络接口信息的获取(InetAddress和NetworkInterface)...

使用java进行网络程序的开发,可以说是一件令人愉悦的事情,对于用惯了C网络接口编程的人来说,当他们首次使用Java开发网络应用程序,会发现java开发网络应用是如此的简单,甚至仅用几分钟时间,您就可以学会这种…