3、继承
面向对象的最大优点是代码重用,而实现代码重用的重要的方法就是通过Python的继承机制。这个继承理解为我们日常说的遗产继承,儿子继承父亲的遗产。类比成编程里对应子类和父类,子类继承父类所有的属性与函数,可以进行重写或者进行扩展以实现更多的功能。
Python中关于继承的规则如下:
- 继承写法:class 子类(父类)。
- 子类可以继承父类的所有属性与方法。
- 子类定义与父类同名的属性与方法会自动覆盖。
- 重写时如果想调用父类的同名方法可以使用super().方法名调用。
- 父类的私有属性、方法不能继承,即__(双下划线)开头的属性名和方法名`。
- 子类可以调用super().init()的方式初始化父类。
① 单继承
所谓的单继承就是只继承一个父类,代码示例如下:
class Bird: def __init__(self, name): self.name = name def can_fly(self, can): self.can = can def __str__(self): return self.name + ("能够" if self.can == True else "不能够") + "飞翔。" class Duck(Bird): # 子类扩展父类中的方法 def set_color(self, color): self.color = color # 重写父类中里的方法 def __str__(self): return self.color + "的" + self.name + ("能够" if self.can == True else "不能够") + "飞翔," + "会游泳。" if __name__ == '__main__': duck = Duck("小鸭子") duck.can_fly(False) duck.set_color("黄色") print(duck)
运行结果如下:
黄色的小鸭子不能够飞翔,会游泳。
另外要注意,父类是无法调用子类方法的,比如下面的代码:
bird = Bird('鸟') bird.can_swin()
运行后直接报错:
Traceback (most recent call last): File "/Users/jay/Project/Python/Book/Chapter 9/9_8.py", line 33, in <module> bird.can_swin() AttributeError: 'Bird' object has no attribute 'can_swin'
② 多继承
多继承就是「同时继承多个父类的属性与方法」,多个父类间用逗号隔开,另外要注意如果父类们中有相同的方法,调用的顺序是:谁在前面先调用
那个父类中的方法,比如有class Person(Name, Sex,Age),三个父类里都有一个show的方法,那么子类调用的是Name里的show()!
你可以通过内置属性__mro__
查看对象搜索方法时的先后顺序。另外,如果不是非得用多继承不可的话,应该尽量避免使用它,有时会出现一些不可遇见的BUG。多继承的代码示例如下:
class A: def show_A(self): print('父类A') class B: def show_B(self): print('父类B') # 定义一个子类,继承A和B类 class C(A, B): def show_C(self): print('子类C') if __name__ == '__main__': c = C() c.show_A() c.show_B() c.show_C()
运行结果如下:
父类A 父类B 子类C
4、组合
多继承的一个替代方案就是通过组合的方式,「把需要用到的类丢到组合类中实例化」,代码示例如下:
class Book: def __init__(self, num): self.num = num class Phone: def __init__(self, num): self.num = num class Wallet: def __init__(self, num): self.num = num class Bag: def __init__(self, x, y, z): self.book = Book(x) self.phone = Phone(y) self.wallet = Wallet(z) def show_bag(self): print("您的背包里有:【书本】* %d 【手机】* %d 【钱包】* %d" % (self.book.num, self.phone.num, self.wallet.num)) if __name__ == '__main__': bag = Bag(3, 2, 1) bag.show_bag()
运行结果如下:
您的背包里有:【书本】* 3 【手机】* 2 【钱包】* 1
5、对象相关的内置函数
Python中还为我们提供了一些与对象相关的内置函数,如下表所示:
函数 | 作用 |
issubclass(class, classinfo) | 如果第一个参数是第二个参数的子类,返回True, 否则返回False |
isinstance(object, classinfo) | 如果第一个参数是第二个参数的实例对象,返回True, 否则返回False |
hasattr(object, name) | 测试一个对象中是否有指定的属性,属性名要用引号 括着! |
getattr(object, name, [,default]) | 返回对象的指定属性值,不存在返回default值, 没设会报ArttributeError异常 |
setattr(object, name, value) | 设置对象中指定属性的值,属性不存在会新建并赋值 |
delattr(object, name) | 删除对象中的指定属性的值,不存在会报ArttributeError异常 |
property(fget,fset,fdel,doc) | 返回一个可以设置属性的属性 |