面向对象之继承
什么是面向对象的继承?
继承(英语:inheritance)是面向对象软件技术当中的一个概念。如果一个类别A“继承自”另一个类别B,就把这个A称
为“B的子类别”,而把B称为“A的父类别”也可以称“B是A的超类”。继承可以使得子类别具有父类别的各种属性和方法,而
不需要再次编写相同的代码。在令子类别继承父类别的同时,可以重新定义某些属性,并重写某些方法,即覆盖父类别的
原有属性和方法,使其获得与父类别不同的功能。另外,为子类别追加新的属性和方法也是常见的做法。 一般静态的面向
对象编程语言,继承属于静态的,意即在子类别的行为在编译期就已经决定,无法在执行期扩充。
class Person: def __init__(self,name,sex,age): self.name =name self.age = age self.sex = sex class Cat: def __init__(self,name,sex,age): self.name = name self.sex =sex self.age =age class Dog: def __init__(self,name,age,sex): self.name =name self.sex =sex self.age = age # 定义三个不同的类 class Animal(object): def __init__(self,name,sex,age): self.name = name self.sex = sex self.age = age # 定义一个Animal父类 class Person(Animal): pass class Dog(Animal): pass class Person(Animal): pass # 派生三个子类
继承的优点:
- 增加了类的耦合性(耦合性不宜多,宜精)。
- 减少了重复代码。
- 使得代码更加规范化,合理化。
继承的分类
父类,又叫基类,超类,上面例子中的Animal就是一个父类。
子类,派生类,由父类派生而成的类,可以调用父类的静态属性和动态方法。
继承:可以分单继承,多继承。
经典类和新式类:
在python2.2版本之前均为经典类,python2.2之后新式类和经典类并存,python3之后取消了经典类的概念、
简单来说,在python2x基类的根如果什么也不写就是经典类,如果python的根为object就为新式类
python3x版本中只有一种类:
python3中使⽤的都是新式类. 如果基类谁都不继承. 那这个类会默认继承 object
单继承
类名,对象执行父类方法
class Aniaml(object): type_name = '动物类' def __init__(self,name,sex,age): self.name = name self.age = age self.sex = sex def eat(self): print(self) print('吃东西') class Person(Aniaml): pass class Cat(Aniaml): pass class Dog(Aniaml): pass # 类名: print(Person.type_name) # 可以调用父类的属性,方法。 Person.eat(111) print(Person.type_name)
执行顺序
class Animal(object): # 1 type_name = "动物类" # 6 def __init__(self,name,sex,age): # 7 self.name = name # 8 self.sex = sex # 9 self.age = age # 10 def eat(self): print(self) print("吃东西") class Person(Animal): # 2 def eat(self): # 11 print("%s 吃饭"%self.name) # 13 class Cat(Animal): # 3 pass class Dog(Animal): # 4 pass p1 = Person("alex","laygirl",34) # 5 p1.eat() # 12 # 结果: alex 吃饭 # 实例化对象时必须执行__init__方法,类中没有,从父类找,父类没有,从object类中找。 # 先要执行自己类中的eat方法,自己类没有才能执行父类中的方法。
同时执行类以及父类中的方法
1.方法一:
如果想执行父类的func方法,这个方法并且子类中也用,那么就在子类的方法中写上:
父类.func(对象,其他参数)
class Aniaml(object): type_name = '动物类' def __init__(self,name,sex,age): self.name = name self.age = age self.sex = sex # 继承父类中的三个静态属性 def eat(self): print('吃东西') class Person(Aniaml): def __init__(self,name,sex,age,mind): Aniaml.__init__(self,name,sex,age) # 方法一 self.mind = mind # 封装mind属性 def eat(self): super().eat() print('%s 吃饭'%self.name) class Cat(Aniaml): pass class Dog(Aniaml): pass p1 = Person('春哥','laddboy',18,'有思想') print(p1.__dict__)
2.利用super,super().func(参数)(父类的重构)
class Animal: def __init__(self,name,sex,age): self.name = name self.sex = sex self.age = age def eat(self): print("动物都需要吃饭") class Human(Animal): def __init__(self,name,sex,age,hobby): super(Human,self).__init__(name,sex,age) # 继承父类中的三个静态属性 self.hobby = hobby def eat(self): super().eat() # 执行父类中的eat方法 print(f"{self.name}都需要吃饭") class Dog(Animal): pass class Cat(Animal): pass H1 = Human("小红","女",18,"看书") H1.eat() # 结果: "动物都需要吃饭" "小红都需要吃饭"
单继承经典练习题:
# 1 class Base: def __init__(self, num): self.num = num def func1(self): print(self.num) class Foo(Base): pass obj = Foo(123) obj.func1() # 123 运⾏的是Base中的func1 # 2 class Base: def __init__(self, num): self.num = num def func1(self): print(self.num) class Foo(Base): def func1(self): print("Foo. func1", self.num) obj = Foo(123) obj.func1() # Foo. func1 123 运⾏的是Foo中的func1 # 3 class Base: def __init__(self, num): self.num = num def func1(self): print(self.num) class Foo(Base): def func1(self): print("Foo. func1", self.num) obj = Foo(123) obj.func1() # Foo. func1 123 运⾏的是Foo中的func1 # 4 class Base: def __init__(self, num): self.num = num def func1(self): print(self.num) self.func2() def func2(self): print("Base.func2") class Foo(Base): def func2(self): print("Foo.func2") obj = Foo(123) obj.func1() # 123 Foo.func2 func1是Base中的 func2是⼦类中的 # 再来 class Base: def __init__(self, num): self.num = num def func1(self): print(self.num) self.func2() def func2(self): print(111, self.num) class Foo(Base): def func2(self): print(222, self.num) lst = [Base(1), Base(2), Foo(3)] for obj in lst: obj.func2() # 111 1 | 111 2 | 222 3 # 再来 class Base: def __init__(self, num): self.num = num def func1(self): print(self.num) self.func2() def func2(self): print(111, self.num) class Foo(Base): def func2(self): print(222, self.num) lst = [Base(1), Base(2), Foo(3)] for obj in lst: obj.func1() # 那笔来吧. 好好算
多继承
class A: def __init__(self,name): self.name = name def show_name(self): print(f"A的名字为{self.name}") class B: def __init__(self,name): self.name = name def show_name(self): print(f"B的名字为{self.name}") class C(A,B): # C同时继承A,B类 pass c = C("A") print(c.name) c.show_name()
在python这种,经典类和新式类继承父类所使用的算法是完全不同的
经典类的多继承
经典类的多继承采用深度优先算法
class A: pass class B(A): pass class C(A): pass class D(B, C): pass class E: pass class F(D, E): pass class G(F, D): pass class H: pass class Foo(H, G): pass
类的: Foo-> H -> G -> F -> E -> D -> B -> A -> C.
新式类的多继承
mro序列
MRO是一个有序列表L,在类被创建时就计算出来
通用计算公式为:
mro(Chird(Base1,Base2)) = [child] + merge(mro(Base1),mro(Base2),[Base1,Base2]) # 其中child继承自Base1,Base2
如果继承一个基类:class B(A)
这时候B的mro序列为
mro(B) = mro(B(A)) = [B] + merge(mro(A) + [A]) = [B] + merge([A] + [A]) = [B,A]
如果继承至多个基类:class B(A1,A2,A3)
mro(B) = mro( B(A1, A2, A3 …) ) = [B] + merge( mro(A1), mro(A2), mro(A3) ..., [A1, A2, A3] ) = ...
计算结果为列表,列表中至少有一个元素即类自己,如上述示例[A1,A2,A3],merge操作是C3算法的核心
表头和表尾
表头:
列表的第一个元素
表尾:
列表中表头以外的元素集合(可以为空)
示例
列表:[A, B, C]
表头是A,表尾是B和C
列表之间的+操作
+操作:
[A] + [B] = [A, B]
(以下的计算中默认省略)
如计算merge( [E,O], [C,E,F,O], [C] ) 有三个列表 : ① ② ③ merge不为空,取出第一个列表列表①的表头E,进行判断 各个列表的表尾分别是[O], [E,F,O],E在这些表尾的集合中,因而跳过当前当前列表 取出列表②的表头C,进行判断 C不在各个列表的集合中,因而将C拿出到merge外,并从所有表头删除 merge( [E,O], [C,E,F,O], [C]) = [C] + merge( [E,O], [E,F,O] ) 进行下一次新的merge操作 ...... ---------------------
计算mro(A)方式:
mro(A) = mro( A(B,C) ) 原式= [A] + merge( mro(B),mro(C),[B,C] ) mro(B) = mro( B(D,E) ) = [B] + merge( mro(D), mro(E), [D,E] ) # 多继承 = [B] + merge( [D,O] , [E,O] , [D,E] ) # 单继承mro(D(O))=[D,O] = [B,D] + merge( [O] , [E,O] , [E] ) # 拿出并删除D = [B,D,E] + merge([O] , [O]) = [B,D,E,O] mro(C) = mro( C(E,F) ) = [C] + merge( mro(E), mro(F), [E,F] ) = [C] + merge( [E,O] , [F,O] , [E,F] ) = [C,E] + merge( [O] , [F,O] , [F] ) # 跳过O,拿出并删除 = [C,E,F] + merge([O] , [O]) = [C,E,F,O] 原式= [A] + merge( [B,D,E,O], [C,E,F,O], [B,C]) = [A,B] + merge( [D,E,O], [C,E,F,O], [C]) = [A,B,D] + merge( [E,O], [C,E,F,O], [C]) # 跳过E = [A,B,D,C] + merge([E,O], [E,F,O]) = [A,B,D,C,E] + merge([O], [F,O]) # 跳过O = [A,B,D,C,E,F] + merge([O], [O]) = [A,B,D,C,E,F,O] ---------------------