029、继承与复用
本文最后更新于 398 天前,其中的信息可能已经过时,如有错误请发送邮件到 wuxianglongblog@163.com

继承与复用

在自定义类型的基本形式中:

class ClassName(ParentClass):
"""class docstring"""
def some_method(self, ...):
return ...

ParentClass 是用来进行继承的,被继承的 ParentClass 是父类,定义的 ClassName 是子类。可以认为子类是一种特殊的父类。

例如,假设父类是哺乳动物,人作为一个子类可以继承这个父类,因为人是哺乳动物的一种;狮子也可以继承哺乳动物,因为狮子也是哺乳动物的一种。

类的继承

考虑这样一个表示树叶的类:

class Leaf(object):
def __init__(self, color='green'):
self.color = color
def fall(self, season="autumn"):
print(f"A leaf falls in {season}!")

继承这个类,生成一个枫树叶类:

class MapleLeaf(Leaf):
def change_color(self):
if self.color == "green":
self.color = "red"

构造一个子类对象:

mleaf = MapleLeaf()

子类会继承父类的属性和方法,父类的属性和方法可以直接调用:

mleaf.fall()
A leaf falls in autumn!
mleaf.color
'green'

子类虽然没有定义构造函数,但是会直接继承父类的构造函数:

mleaf2 = MapleLeaf("orange")
mleaf2.color
'orange'

子类额外定义的方法:

mleaf.change_color()
mleaf.color
'red'

方法的重载

子类可以对父类中已有的方法进行重载。例如,在枫树叶类中对.fall() 方法进行重载,即重新定义:

class MapleLeaf(Leaf):
def change_color(self):
if self.color == "green":
self.color = "red"
def fall(self, season="autumn"):
self.change_color()
print(f"A leaf falls in {season}!")

在这个例子中,.fall() 方法被重载,并调用了自定义类中的已有方法。方法定义中的第一个参数 self 表示的就是对象自身,所以可以用 self.change_color() 实现对已有方法的调用:

mleaf = MapleLeaf()
mleaf.color
'green'
mleaf.fall()
A leaf falls in autumn!
mleaf.color
'red'

super () 函数

与父类的.fall () 方法相比,子类的方法只增加了.change_color () 的调用,之后的操作与父类的.fall () 方法一致,代码其实有冗余和浪费。Python 提供了 super() 函数,在子类中调用父类的方法。具体定义如下:

class MapleLeaf(Leaf):
def change_color(self):
if self.color == "green":
self.color = "red"
def fall(self, season="autumn"):
self.change_color()
super(MapleLeaf, self).fall(season)
# print(f"A leaf falls in {season}!")

能实现与上面一样的结果:

mleaf = MapleLeaf()
mleaf.color
'green'
mleaf.fall()
A leaf falls in autumn!
mleaf.color
'red'

鸭子类型:一切都是为了复用

鸭子类型(Duck Type)的概念来源于美国诗人詹姆斯・惠特科姆・莱利的诗句:“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。” 在 Python 中,这个概念被衍生为:在使用对象时,可以不关注对象的类型,而关注对象具有的方法或属性;只要对象的属性和方法满足条件,就认为该对象是合法的。

例如,定义这样的一个函数:

def something_fall(leaf):
leaf.fall()

这个函数接受一个参数 leaf,并调用它的.fall () 方法。Leaf 类支持.fall () 方法,因此该类型的对象是合法的:

leaf = Leaf()
something_fall(leaf)
A leaf falls in autumn!

子类 MapleLeaf 也支持.fall () 方法,所以也是合法的对象:

mleaf = MapleLeaf()
something_fall(mleaf)
A leaf falls in autumn!

再定义一个类苹果:

class Apple(object):
def fall(self):
print("An apple falls!")
apple = Apple()
something_fall(apple)
An apple falls!

在鸭子类型机制下,Python 将函数和方法中的类型检查,变成了接口检查的模式,即 something_fall () 函数不会检查传入的参数 leaf 是什么类型,而是检查 leaf 有没有实现.fall () 接口。

谨此笔记,记录过往。凭君阅览,如能收益,莫大奢望。
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇