4.2继承者们
1.子类
类别本身还可以进一步细分成子类。比如说,鸟类可以进一步分成?鸡、天鹅。在面向对象编程中,我们通过继承(Inheritance)来表达上述概念。
class Bird(object):
feather=True
reproduction = "egg"
def chirp(self,sound):
print(sound)
class Chicken(Bird):
how_to_move = "walk"
edible = True
class Swan(Bird):
how_to_move = "swim"
edible = False
summer = Chicken()
print(summer.feather)
summer.chirp("ji")
_________________________
True
ji
新定义的鸡(Chicken)类,增加了两个属性:移动方式(how_to_move)?和可以食用(edible)
在类定义时,括号里为Bird。这说明,鸡类是属于鸟类(Bird)的一?个子类,尽管只声明summer是鸡类,但它通继承享有了父类的属性,比如数据性的属性feather,还有方法性的属性?chirp()。新定义的天鹅(Swan)类,同样继承自鸟类。在创建一个天鹅对象时,该对象自动拥有鸟类的属性。通过继承来减少程序中的重复信息和重复语句,继承提高了程序的可重复使用性。类object其实是Python中的一个内置类。它充当了所有类的祖先。
分类往往是人了解世界的第一步。卡尔?林奈提出一个分 类系统,通过父类和子类的隶属关系,为进一步的科学发现铺平了道路。 面向对象语言及其继承机制,正是模拟人的有意识分类过程。
2.属性覆盖
如上所述,在继承的过程中,可以在子类中增加父类不存在的属性,从而增强子类的功能;还可以在子类中替换父类己经存在了的属性,比如:
class Bird(object):
def chirp(self):
print ("make sound")
class Chicken(Bird):
def chirp(self):
super().chirp()
print("ji")
bird = Bird()
bird.chirp()
#?打印?'make sound summer = Chicken()
summer = Chicken()
summer.chirp()
# 打印"make sound"和"ji"
_____________________________________
make sound
make sound
ji
鸡类(Chicken)是鸟类(Bird)的子类。在鸡类(Chicken)中定义方法chirp()。这个方法在鸟类中也有定义。通过调用可以看出,鸡类会调用自身定义的chirp()方法,而不是父类中的chirp()方法。从效果上看,这就好像父类中的方法chirp()被子类中的同名属性覆盖(override)?了一样。
通过对方法的覆盖可以彻底地改变子类的行为。但有时候,子类的行为是父类行为的拓展,这时可以通过super关键字在子类中调用父类中被覆盖的方法,比如:
class Bird(object):
def chirp(self):
print("make sound")
class Chicken(Bird):
def chirp(self):
super().chirp()
print("ji")
bird = Bird()
bird.chirp()
#?打印"make sound"
summer = Chicken()
summer.chirp()
#?打印"make sound"和”ji”
___________________________
ji
make sound
make sound
在鸡类的chirp()方法中,我们使用了super。它是一个内置类,能产生一个指代父类的对象,在子类的同名方法中调用父类的方法。这样,子类的方法既能执行父类中的相关操作,又能定义属于自己的额外操作。
调用super的语句可以出现在子类方法的第一句,也可以出现在子类方法的任意其他位置。
|