继承与多态
一、继承
-
什么是继承?
继承就是新建类的一种方式,新建的类叫作子类或者派生类,被继承的类叫作父类或者基类
-
为什么要用继承
是为了解决类与类之间代码的冗余
-
新式类和经典类(python 2中所特有的)
python 2 和python 3中的类有点不同。在python 2中,类被分为新式类和经典类,新式类是继承了object类的子子孙孙都叫新式类,没有继承object类的子子孙孙都叫经典类。而在python 3中,所有的类都默认继承了object类。
-
继承的使用
# 子类可一继承父类当中的方法 class School: def __init__(self, name, age, gender): self.name = name self.age = age self.gender = gender class Teacher(School): def __init__(self, name, age, gender, salary): self.salary = salary School.__init__(self, name, age, gender) def score(self, stu_obj, goals): stu_obj.goals = goals print('%s给%s打了%s分' % (self.name, stu_obj.name, goals)) class Student(School): def __init__(self, name, age, gender): School.__init__(self, name, age, gender) def get_course(self, course=None): if course == None: course = [] self.courses = course stu1 = Student('lily', 18, 'female') teacher1 = Teacher('Mr Right', 28, 'female', 30000) teacher1.score(stu1, 100) print(stu1.__dict__) # Mr Right给lily打了100分 # {'name': 'lily', 'age': 18, 'gender': 'female', 'goals': 100} print(teacher1.__dict__) # {'salary': 30000, 'name': 'Mr Right', 'age': 28, 'gender': 'female'}
二、属性查找
-
单继承下的属性查找
# 案例一 class Foo: def f1(self): print('from FOO') class Bar(Foo): def f2(self): self.f1() print('from Bar') obj1 = Bar() obj1.f2() # from FOO # from Bar
# 案例二 class Foo: def __f1(self): print('f1 from Foo') def f2(self): print('from FOO') self.__f1() class Bar(Foo): def __f1(self): print('from Bar') obj1 = Bar() obj1.f2() # from FOO # f1 from Foo
-
多继承下的属性查找
原则:新式类按照广度优先的原则,经典类按照深度优先的原则
# 案例一:经典类 class V: def f3(self): print('f1 from V') class H(V): def f2(self): print('f2 from H') class A(H): def f1(self): print('f1 from A') class N(V): def f2(self): print('f2 from N') class B(N): def f1(self): print('f1 from B') def f4(self): print('f4 from B') class S(A, B): pass obj1 = S() obj1.f1() # f1 from A obj1.f2() # f2 from H obj1.f3() # f1 from V obj1.f4() # f4 from B
# 案例二:新式类 class A(object): def test(self): print('from A') class B(A): def test(self): print('from B') pass class C(A): def test(self): print('from C') pass class D(B): def test(self): print('from D') pass class E(C): def test(self): print('from E') pass class F(D, E): def test(self): print('from F') pass f1 = F() f1.test() # 全部留下 >>> from F # 注释掉F下面的test >>> from D # 注释掉F、D下面的test >>> from B # 注释掉F、D、B下面的test >>> from E # 注释掉F、D、B、E下面的test >>> from C # 注释掉F、D、B、E、C下面的test >>> from A
-
super()和mro列表
# super() class People(): school = 'SH' def __init__(self, name, age, gender): self.name = name self.age = age self.gender = gender class Teacher(People): def __init__(self, name, age, gender, level): self.level = level super().__init__(name, age, gender) # super的使用
.mro()
class A: def test(self): print('from A.test') super().test() class B: def test(self): print('from B') class C(A, B): pass print(C.mro()) # [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>] c = C() c.test() # from A.test # from B
三、多态与多态性
-
抽象类: 抽象类只能被继承,不能被实例化
class Animal(metaclass=abc.ABCMeta): @abc.abstractmethod # 该方法已经是抽象方法了 def speak(self): pass @abc.abstractmethod def login(self):pass class People(Animal): def speak(self): # print('嗷嗷嗷') pass def login(self): pass class Pig(Animal): def speak(self): print('哼哼哼') class Dog(Animal): def speak(self): print('汪汪汪') obj = People() obj.speak()
-
多态带来的特性:在不用考虑对象数据类型的情况下,直接调用对应的函数
def animal(animal): return animal.speak() animal(obj) animal(obj1) animal(obj2) animal(obj3) # 父类限制子类的行为 class Animal(): def speak(self): raise Exception("必须实现speak方法")