029、继承与复用
本文最后更新于 67 天前,其中的信息可能已经过时,如有错误请发送邮件到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
小恐龙
花!
上一篇
下一篇