如果你需要设计一个“水陆两栖机器人”,它既要能在陆地上移动,又要能在水中巡游,你会如何设计它的代码结构?是选择写一个庞大而复杂的类,还是有更优雅的方式让它同时拥有“车”和“船”的特性?
什么是多继承?
Python语言是少数支持多继承的一门编程语言,所谓的多继承就是允许一个类同时继承自多个类的特性。
基本语法:
class B(object): passclass C(object): passclass A(B, C): passa = A()a.B中的所有属性和方法a.C中的所有属性和方法
汽油车、电动车 => 混合动力汽车(汽车 + 电动)
class GasolineCar(object): def run_with_gasoline(self): print('i can run with gasoline')class EletricCar(object): def run_with_eletric(self): print('i can run with eletric')class HybridCar(GasolineCar, EletricCar): passtesla = HybridCar()tesla.run_with_gasoline()tesla.run_with_eletric()
注意:虽然多继承允许我们同时继承自多个类,但是实际开发中,应尽量避免使用多继承,因为如果两个类中出现了相同的属性和方法就会产生命名冲突。
扩展特性:继承让子类继承父类的所有公共属性和方法,但是如果仅仅是为了继承公共属性和方法,继承就没有实际的意义了,应该是在继承以后,子类应该有一些自己的属性和方法。
什么是重写?
重写也叫作覆盖,就是当子类成员与父类成员名字相同的时候,从父类继承下来的成员会重新定义!
此时,通过子类实例化出来的对象访问相关成员的时候,真正其作用的是子类中定义的成员!
上面单继承例子中 Animal 的子类 Cat和Dog 继承了父类的属性和方法,但是我们狗类Dog 有自己的叫声'汪汪叫',猫类 Cat 有自己的叫声 '喵喵叫' ,这时我们需要对父类的 call() 方法进行重构。如下:
class Animal(object): def eat(self): print('i can eat') def call(self): print('i can call')class Dog(Animal): passclass Cat(Animal): passwangcai = Dog()wangcai.eat()wangcai.call()miaomiao = Cat()miaomiao.eat()miaomiao.call()
Dog、Cat子类重写父类Animal中的call方法:
class Animal(object): def eat(self): print('i can eat') def call(self): print('i can call')class Dog(Animal): # 重写父类的call方法 def call(self): print('i can wang wang wang')class Cat(Animal): # 重写父类的call方法 def call(self): print('i can miao miao miao')wangcai = Dog()wangcai.eat()wangcai.call()miaomiao = Cat()miaomiao.eat()miaomiao.call()
思考:重写父类中的call方法以后,此时父类中的call方法还在不在?
答:还在,只不过是在其子类中找不到了。类方法的调用顺序,当我们在子类中重构父类的方法后,Cat子类的实例先会在自己的类 Cat 中查找该方法,当找不到该方法时才会去父类 Animal 中查找对应的方法。
super():调用父类属性或方法,完整写法:super(当前类名, self).属性或方法(),在Python3以后版本中,调用父类的属性和方法我们只需要使用super().属性或super().方法名()就可以完成调用了。
Car汽车类、GasolineCar汽油车、ElectricCar电动车
class Car(object): def __init__(self, brand, model, color): self.brand = brand self.model = model self.color = color def run(self): print('i can run')class GasolineCar(Car): def __init__(self, brand, model, color): super().__init__(brand, model, color) def run(self): print('i can run with gasoline')class ElectricCar(Car): def __init__(self, brand, model, color): super().__init__(brand, model, color) # 电池属性 self.battery = 70 def run(self): print(f'i can run with electric,remain:{self.battery}')bwm = GasolineCar('宝马', 'X5', '白色')bwm.run()tesla = ElectricCar('特斯拉', 'Model S', '红色')tesla.run()
今日学习完毕,课后作业:
多继承的方法调用顺序,题目要求:
① 创建两个父类 Teacher和 Student,每个类中定义一个同名方法 introduce(),但实现不同:
Teacher的 introduce()返回 "我是一名老师"。
Student的 introduce()返回 "我是一名学生"。
② 创建一个子类 TeachingAssistant,同时继承 Teacher和 Student(顺序为先 Teacher后 Student)。
③ 在子类中不重写 introduce()方法。
④ 实例化 TeachingAssistant类,调用其 introduce()方法,观察输出并解释原因。