Python面向对象03 /继承
Python面向对象03 /继承
1. 初识继承
- 概念:专业角度:如果B类继承A类,B类就称为子类,派生类,A类就称为父类,超类,基类
- 种类:单继承,多继承
- 面向对象的三大特征:继承,封装,多态
- 继承的优点:
- 减少重复的代码
- 增加类之间的耦合性(不宜多,宜精)
- 使代码更清晰,合理化
2. 单继承
-
定义:只有一个父类
-
执行父类的属性和方法:
1.类名执行父类的属性和方法
2.派生类对象执行父类的属性和方法
1.查询顺序:
单向不可逆,子类可以使用父类的属性和方法,父类不可以使用子类的属性和方法 2.实例化对象时必须执行
__init__
方法,类中没有,从父类找,父类没有,从object类中找。 -
既要执行子类的方法,又要执行父类的方法
方法一:不依赖继承 / 父类.func(对象,其他参数)
class Animal(object): type_name = "动物类" def __init__(self,name,sex,age): self.name = name self.age = age self.sex = sex def eat(self): print("吃东西") class Person(Animal): def __init__(self,name,sex,age,mind): Animal.__init__(self,name,sex,age) self.mind = mind def eat(self): super().eat() print(f'{self.name}会吃饭') p1 = Person("张三","男",18,"有思想") p1.eat()
方法二:依赖继承 / 利用super
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): {super(Person,self).__init__(name,sex,age)} (完整写法) super().__init__(name,sex,age) self.mind = mind def eat(self): super().eat() print('%s 吃饭'%self.name) class Cat(Aniaml): pass p1 = Person('张三','男',18,'有思想') print(p1.__dict__) # 利用super,super().func(参数) # super.__init__执行父类 # 执行父类的__init__方法,重构父类方法.
单继承应用示例:
class Base: def __init__(self,num): self.num = num def func1(self): print(self.num) self.func2() def func2(self): print(222,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() # 结果: 1 222 1 2 222 2 3 222 3
-
单继承总结:
- 面向对象中super的作用:
super().func(参数) 重构父类的方法,严格按照对象从属类的mro顺序执行
3. 多继承
-
Python类分为两种:
经典类:不继承object类,深度优先原则,深度优先.从左至右,深度优先.
新式类:继承object类,mro(C3)算法(新式类查询顺序) -
Python2x:Python2.2之前都是经典类,Python2.2之后,经典类和新式类共存
Python3x:全都是新式类,如果基类谁都不继承,那这个类会默认继承object类 -
新式类推导示例:
class O: name = '张三' class D(O): pass class E(O): name = '李四' # pass class F(O): name = '王五' class B(D,E): pass class C(E,F): pass class A(B,C): pass obj = A() print(obj.name) # mro(Child(Base1,Base2)) = [ Child ] + merge( mro(Base1), mro(Base2), [ Base1, Base2] ) # mro(A(B,C)) = [A] + merge(mro(B),mro(C),[B,C]) ''' mro(A(B,C)) = [A] + merge(mro(B),mro(C),[B,C]) mro(B(D,E)) = [B] + merge(mro(D),mro(E),[D,E]) mro(B(D,E)) = [B] + merge([D,O],[E,O],[D,E]) mro(B(D,E)) = [B,D] + merge([O],[E,O],[E]) mro(B(D,E)) = [B,D,E] + merge([O],[O]) mro(B(D,E)) = [B,D,E,O] mro(C) = [C,E,F,O] mro(A(B,C)) = [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]) = [A,B,D,C] + merge([E,O],[E,F,O]) = [A,B,D,C,E] + merge([O],[F,O]) = [A,B,D,C,E,F,O] ''' # print(A.mro())
-
经典类推导示例:见下面示例
4. 总结
-
类的静态属性,如果指向一个可变数据类型,对象或者类名都可以给这个可变数据类型内部增,删,改,查(不可以对其整体增,删,改,查)
示例代码:
class A: name = [] p1 = A() p2 = A() p1.name.append(1) # p1.name,p2.name,A.name 分别是什么? # 结果:[1],[1],[1]
-
新式类,经典类示例
class A: pass class B(A): pass class C(A): pass class D(A): pass class E(B, C): pass class F(C, D): pass class G(D): pass class H(E, F): pass class I(F, G): pass class K(H, I): pass # 如果这是经典类,请写出他的继承顺序。 KHEBACFDIG # 如果这是新式类,请写出他的继承顺序,并写出具体过程。 KHEBIFCGDA