前言:
上一关,我们知道了面向对象编程的重要性,也学习了类的基础知识(1.面向对象编程,2.类的创建和调用,3.创建类的两个关键点)。在此,你可以回忆一会,想想是不是都掌握了。
回顾一下代码:
这一关,我们会拓展类的知识疆界,探索两个类的拓展玩法:类的定制和类的继承。说是拓展,是因为这两个知识点属于类中较高阶的操作,让用类写成的代码更容易复用、拓展和维护(这些优势在了解继承和定制后,就能理解了)。
类的继承和定制
基础概念
在Python中,我们的习惯表述是:A类是B类的子类,而B类是A类的父类(或超类)。所以,类的继承,让子类拥有了父类拥有的所有属性和方法。如此,不用白手起家(从头写代码),直接一夜暴富(代码的复用)。
不过,只有继承的话,子类只是父类的复制而已。那样,为什么不直接用父类,还要增加一个子类?要回答这个问题,就需要了解另一个重要的概念:类的定制。
还是说回广东人,广东人除了继承中国人的属性方法外,还可以创造【属于自己】的属性或方法,如籍贯开头是广东省(属性)、会说广东话(方法)。子类也可以在继承的基础上进行个性化的定制,包括:(1)创建新属性、新方法;(2)修改继承到的属性或方法。
简而言之:类的定制,不仅可以让子类拥有新的功能,还能让它有权修改继承到的代码——在写这句话时,我仿佛看到子类化成了一个人,抬头瞟了一眼在他上方的父类,淡淡地说了一句话:以我为主,为我所用。
类的继承
继承的基础语法
用代码表示继承,语句是:
子类继承的属性和方法,也会传递给子类创建的实例。
可见:通过一个小括号,子类就能轻轻松松地拥有父类所拥有的一切。不用复制大段大段的代码,只要一个括号,就能复用整块代码。
不过,很多类在创建时也不带括号,如class Chinese:。这意味着它们没有父类吗?并不。实际上,class Chinese:在运行时相当于class Chinese(object):。而object,是所有类的父类,我们将其称为根类(可理解为类的始祖)。
我们可以用一个函数来验证这一点:函数isinstance(),可以用来判断某个实例是否属于某个类。具体用法是输入两个参数(第一个是实例,第二个是类或类组成的元组),输出是布尔值(True 或 False)。跑下代码你就完全懂了:
总结一下:
类的继承之多层继承
继承不仅可以发生在两个层级之间(即父类-子类),还可以有父类的父类、父类的父类的父类……
可得结论:子类创建的实例可调用所有层级父类的属性和方法。
类的继承之多重继承
一个类,可以同时继承多个类,语法为class A(B,C,D):。假设我们将“出生在江苏,定居在广东的人”设为一个类Yuesu,那么,它的创建语句则为class Yuesu(Yue,Su)。
class Yuesu(Yue,Su)括号里Yue和Su的顺序是有讲究的。和子类更相关的父类会放在更左侧。我认为“出生在江苏,定居在广东的人”在穿着和饮食等方面会更接近广东人,所以将 Yue 放在 Su 的左侧。所以,广东人创建的实例在调用属性和方法时,会先在左侧的父类中找,找不到才会去右侧的父类找。(可理解为“就近原则”)
请你根据就近原则,推测下面代码会打印出什么
对比一下这两种有趣的继承方法:
请你尝试用代码完成下面的继承关系,按照下图类名和属性创建5个类,并打印出C4类的实例的属性name和num
多重继承中,若某父类还有父类的话,会先继续往上找到顶,纵向优先级比横向优先级高
类的定制
定制,可以新增代码
可见:我们可以在子类下新建属性或方法,让子类可以用上父类所没有的属性或方法。这种操作,属于定制中的一种:新增代码。
定制,也可重写代码
显然,这样对代码的维护很不友好。假设有34个子类需定制这个方法,都是直接重写。那么,假设父类的方法改变,如说法改为“我们脚下的大地的面积有960万平方公里”。那么,就需要将所有子类的代码中的说法也改变。
下面介绍更优雅的重写方式:
参数增加
子类继承父类方法的操作是在def语句后接父类.方法(参数)。这样一来,父类方法land_area中的说法改变,子类也不用去动,因为子类直接继承了父类的方法。只不过,在继承的基础上,通过参数的调整完成了定制。
而参数的调整,可以增加参数(如 rate),也可以【改变参数的默认值】,如下:
下面,请你通过参数默认值的改变,完成子类的定制,让程序的运行结果为“雷猴!欢迎来到广东。”
课后练习:
每个人都有好几个不同的身份,且不同身份都附带一些特定的特征(属性)和行为(方法)。
例如,有这样一群人:在学校时被归在老师,脸是严肃的;亲子关系中(parenthood)则被归到父亲,脸是甜蜜的。
下面,我们就以这群人为例,探索类属性在类的继承和定制中的传递和改变
发布者:LJH,转发请注明出处:https://www.ljh.cool/7883.html