目录
Python面向对象03/继承
内容大纲
1.初识继承
2.继承的优点
3.单继承
4.多继承
1.初识继承
#字面上的意思是儿子完全使用父亲的所有内容
#专业角度:如果B类继承A类
# B类就称为子类,派生类
# A类就称为父类,超类,基类
面向对象的三大特征:
继承,封装,多态
#继承可以分为单继承/多继承
2.继承的优点
#1.减少重复的代码
#2.增加类之间的耦合性(不宜多,宜精)
#3.使代码更清晰,合理化
3.单继承
3.1类名执行父类的属性和方法
3.2派生类对象,执行父类的属性和方法
#查询顺序:
# 单向不可逆,子类可以使用父类的属性和方法,父类不可以使用子类的属性和方法
实例化对象时必须执行__init__方法,类中没有,从父类找,父类没有,从object类中找。
3.3既要执行子类的方法,又要执行父类的方法
方法一:不依赖继承
父类.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,super().func(参数)
super.__init__执行父类
执行父类的__init__方法,重构父类方法.
#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__)
练习一:
# class Base:
# def __init__(self,num):
# self.num = num
# def func1(self):
# print(self.num)
# class Foo(Base):
# pass
# obj = Foo(123)
# obj.func1()
练习二:
# 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()
练习三:
# 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()
练习四:
# 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()
练习五:
# 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()
4.多继承
Python类分为两种:
1.经典类:
不继承object类,深度优先原则
2.新式类:
继承object类,mro(C3)算法(新式类查询顺序)
Python2x:
Python2.2之前都是经典类,Python2.2之后,经典类和新式类共存
Python3x:
全都是新式类,如果基类谁都不继承,那这个类会默认继承object类
# class Shenxian:
# def fly(self):
# print("神仙都会飞")
# class Monkey:
# def climb(self):
# print("猴子会爬树")
# class Sunwukong(Shenxian,Monkey):
# pass
# sxz = Sunwukong()
# sxz.climb()
# sxz.fly()
# 经典类: 深度优先.从左至右,深度优先.
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())
在python2x版本中存在两种类.:
⼀个叫经典类. 在python2.2之前. ⼀直使⽤的是经典类. 经典类在基类的根如果什么都不写.
⼀个叫新式类. 在python2.2之后出现了新式类. 新式类的特点是基类的根是object类。
python3x版本中只有一种类:
python3中使⽤的都是新式类. 如果基类谁都不继承. 那这个类会默认继承 object
5.今日练习
# 1.简答题:
# 1.面向对象的三大特性是什么?
# 继承,封装,多态
# 2.什么是面向对象的新式类?什么是经典类?
# 新式类:如果基类谁都不继承,那这个类会默认继承object
# 经典类:不继承object类,深度优先原则
# 3.面向对象为什么要有继承?继承的好处是什么?
# 1.减少重复代码
# 2.增加类之间的耦合性
# 3.使代码更清晰,合理化
# 4.面向对象中super的作用。
# super().func(参数) 重构父类的方法
#
# 2.代码题(通过具体代码完成下列要求):
# class A:
# def func(self):
# print('in A')
# class B:
# def func(self):
# print('in B')
# class C(A, B):
# def func(self):
# print('in C')
#可以改动上上面代码,完成下列需求:对C类实例化一个对象产生一个c1,然后c1.func()
#1.让其执行C类中的func
#2.让其执行A类中的func
#3.让其执行B类中的func
#4.让其既执行C类中的func,又执行A类中的func
#5.让让其既执行C类中的func,又执行B类中的func
# 1.
# c1 = C()
# c1.func()
# 2.
# A.func(111)
# 3.
# B.func(111)
# 4.
# class A:
# def func(self):
# print('in A')
# class B:
# def func(self):
# print('in B')
# class C(A, B):
# def func(self):
# super().func()
# print('in C')
# c1 = C()
# c1.func()
# 5.
# class A:
# def func(self):
# print('in A')
# class B:
# def func(self):
# print('in B')
# class C(A, B):
# def func(self):
# super(A,self).func()
# print('in C')
# c1 = C()
# c1.func()
#
3.下面代码执行结果是什么?为什么?
# class Parent:
# def func(self):
# print('in Parent func')
# def __init__(self):
# self.func()
# class Son(Parent):
# def func(self):
# print('in Son func')
# son1 = Son()
# in Son func
#
4.
# class A:
# name = []
# p1 = A()
# p2 = A()
# p1.name.append(1)
# p1.name,p2.name,A.name 分别是什么?
# [1],[1],[1]
类的静态属性,如果指向一个可变数据类型,对象或者类名都可以给这个可变数据类型内部增,删,改,查(不可以对其整体增,删,改,查)
# p1.age = 12
# p1.age,p2.age,A.age 分别又是什么?为什么?
# 12 ,报错,报错
#
5.写出下列代码执行结果:
# class Base1:
# def f1(self):
# print('**base1.f1**')
#
# def f2(self):
# print('**base1.f2**')
#
# def f3(self):
# print('**base1.f3**')
# self.f1()
# class Base2:
# def f1(self):
# print('**base2.f1**')
# class Foo(Base1, Base2):
# def f0(self):
# print('**foo.f0**')
# self.f3()
# obj = Foo()
# obj.f0()
# **'foo.f0' **
# **'base1.f3' **
# **'base1.f1' **
#
5. 看代码写结果:
# class Parent:
# x = 1
# class Child1(Parent):
# pass
# class Child2(Parent):
# pass
# print(Parent.x, Child1.x, Child2.x)
# 1 1 1
# Child2.x = 2
# print(Parent.x, Child1.x, Child2.x)
# 1 1 2
# Child1.x = 3
# print(Parent.x, Child1.x, Child2.x)
# 1 3 2
#
# 6.有如下类:
# 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
经典类流程图