Day09 - 子类父类多继承多层继承多态
创始人
2024-05-16 05:02:42

1. 子类中访问父类中的私有属性和私有方法

如果想使用父类中的私有属性和私有方法,那么就需要在父类中,为这些私有的属性和方法,提供相应的公有的接口方法来间接访问

2. 如何为父类中的属性进行初始化

在子类中如果定义了自己的初始化方法,那么这时父类的初始化方法就不会再执行了
那么就导致父类中定义的属性无法初始化,子类对象就无法使用继承自父类的属性
如果想正常初始化,需要在子类的初始化方法中,手动调用父类的初始化方法
现阶段调用格式:
父类名.__init__(self,父类中需要属性参数列表)
'''
子类初始化父类的属性
'''# 父类
class Father(object):def __init__(self,name):print('Father Init Run ...')self.name = name# 子类
class Son(Father):def __init__(self,name, age):# 因为子类提供了 init 方法后,那么在使用子类实例对象时,就会调用 子类自己 init 方法,# 那么就不会再调用 父类的init方法了,父类当中的属性就不会有绑定的机会,所以这时是没有父类的属性的# 如果想父类中的属性可以得到,需要执行父类中的init方法# 父类名.init()Father.__init__(self, name)print('Son Init run ..')self.age = age# 测试
s = Son('Tom', 12)
print(s.name)
print('age:', s.age)

3. 子类中重写和调用父类的方法

在子类继承父类时,子类会拥有父类中的方法.
但是子类并不需要或不满足父类方法中提供的功能,这时就需进行对父类方法重写重写之后,调用该方法时,执行谁?
答案: 调用重写后子类中的方法
'''
子类重写父类中的方法
'''# 父类
class Father(object):# 实现一个治病def cure(self):print('父类是个老中医,使用中医古法治病')# f = Father()
# f.cure()# 子类
class Son(Father):# 子类也是一个大夫,也有治病的功能def cure(self):# 直接使用 父类名.方法名 形式来引用父类的功能Father.cure(self)print('子类出国深造,学成以后,使用中西医结合方法治病')s = Son()
s.cure()

4. 子类方法中调用父类的同名方法

子类调用父类同名方法,第一种方法是:指名道姓,重新在子类中将每个父类方法调用一遍,这种方法代码冗余,但是有多继承的话,也能解决问题;第二种方法是:使用super代替父类的名字调用父类,因此要调用爷爷类的同名方法,那就要在父类中同样使用super代替,所以说super方法比较适合单一继承。

#  super无参数写法
super().__init__()
super().要调用的函数()

5. 多层继承

继承关系有多层,祖孙三代查找方法:父类名.方法名(self)
'''
多层继承
'''class A(object):def a(self):print('a function')class B(A):def b(self):print('b function')class C(B):# C类中重写了B类中的方法def b(self):B.b(self)print('b in C function')def c(self):print('c function')class D(C):def d(self):print('d function')# 测试
d = D()
d.a()
d.b()
d.c()
d.d()
'''
多层继承
'''class A(object):def __init__(self, a):self.a = aclass B(A):def __init__(self, a, b):A.__init__(self, a)self.b = bclass C(B):def __init__(self, a, b, c):B.__init__(self, a, b)self.c = cclass D(C):def __init__(self, a, b, c, d):C.__init__(self, a, b, c)self.d = d# 测试
d = D(1, 2, 3, 4)
print(d.a)
print(d.b)
print(d.c)
print(d.d)d.__dict__#保存信息到字典
D.__dict__

6. 多继承

格式:
class 类名(父类名1,.....):pass
'''
多层继承:纵向
多继承: 横向'''# 定义一个父亲类
class Father(object):def func_fa(self):print('Father Function ...')# 定义一个母亲类
class Mother(object):def func_mo(self):print('Mother function ...')# 上面的两个类,有一个共同子类
class Son(Father, Mother):def play(self):print('Son play...')# 测试
s = Son()
s.play()
s.func_fa()
s.func_mo()

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

7. 多继承的初始化

'''
多继承的初始化问题
'''# 定义一个人类
# 在这种 继承关系 上,这个共同的父类 Person 会被初台化多次,这是继承时的问题
# 是否 父类名调用 实始化方法的时候 引起的
class Person(object):def __init__(self, aaa):print('Person Init ...')self.aaa = aaaclass Father(Person):def __init__(self, aaa, name):Person.__init__(self, aaa)print('Father Init ...')self.name = nameclass Mother(Person):def __init__(self, aaa, age):Person.__init__(self, aaa)print('Mother Init ...')self.age = ageclass Son(Father, Mother):def __init__(self, aaa, name, age, gender):Father.__init__(self, aaa, name)Mother.__init__(self, aaa, age)print('Son Init ...')self.gender = gender# 测试
s = Son(1, 'Tom', 12, '男')
print(s.aaa)
print(s.name)
print(s.age)
print(s.gender)
'''
多继承的初始化问题的解决
'''# 定义一个人类class Person(object):def __init__(self, aaa):print('Person Init ...')self.aaa = aaaclass Father(Person):def __init__(self, aaa, name, age):super(Father, self).__init__(aaa, age)print('Father Init ...')self.name = nameclass Mother(Person):def __init__(self, aaa, age):super(Mother, self).__init__(aaa)print('Mother Init ...')self.age = ageclass Son(Father, Mother):def __init__(self, aaa, name, age, gender):# 参数二是当前类的实例对象# 参数一是当前类名# 在参数二对象的所属类的mro关系 中找参数一的下一个类进行实始化super(Son, self).__init__(aaa, name, age)print('Son Init ...')self.gender = gender# 测试
s = Son(1, 'Tom', 12, '男')
print(s.aaa)
print(s.name)
print(s.age)
print(s.gender)print(Son.__mro__)
'''
这个顺序关系是解释器在执行代码 时,自动确认的我们无法干涉
(,, , , )
'''# f = Father('tom',1)
print(Father.__mro__)
父类名调用  理解
super()调用  使用
super(类名,self) 了解 
'''
多继承的初始化问题的解决
'''# 定义一个人类class Person(object):def __init__(self, aaa):print('Person Init ...')self.aaa = aaaclass Father(Person):def __init__(self, name, *args):# super(Father, self).__init__(*args)super().__init__(*args)print('Father Init ...')self.name = nameclass Mother(Person):def __init__(self, age, *args):# super(Mother, self).__init__(*args)super().__init__(*args)print('Mother Init ...')self.age = ageclass Son(Father, Mother):def __init__(self, gender, name, age, aaa):# 参数二是当前类的实例对象# 参数一是当前类名# 在参数二对象的所属类的mro关系 中找参数一的下一个类进行实始化# super(Son, self).__init__(name,age,aaa)super().__init__(name, age, aaa)print('Son Init ...')self.gender = gender# 测试
# s = Son(1, 'Tom',12,'男')
s = Son('男', 'Tom', 12, 1)
print(s.aaa)
print(s.name)
print(s.age)
print(s.gender)print(Son.__mro__)
'''
这个顺序关系是解释器在执行代码 时,自动确认的我们无法干涉
(,, , , )
'''f = Father('Jack', 2)
print(f.aaa)
print(f.name)
print(Father.__mro__)
super执行过程:
在 self 这个对象的所属类中,通过 __mro__ 找到方法解析顺序
在顺序中,找当前类名的下一个类来初始化或查找方法
'''
类的继承书写顺序会影响mro顺序
'''class A(object):passclass B(A):passclass C(A):pass# class D(B,C):
# (, < class '__main__.B' >, < class '__main__.C' >, < class '__main__.A' >, < class 'object' > )class D(C, B):# (, , , , )passprint(D.__mro__)
在多继承时,如果继承的多个类同时继承同一个父类,那么这时会出现初始化问题
这个共同父类会被初始化多次.类名.__mro__ 得到了一个元组,元组中的元素是当前类在继承关系上的一个顺序方法解析顺序
method relational ordered这个顺序不是我们确定的,是由在确定某个类的继承关系关系后,由解释器来确定这个顺序
'''
多重多继承时,方法的查找顺序也参考MRO
'''class A(object):def show(self):print('A _ Show Run ...')def info(self):print('A - Info run ...')class B(A):def show(self):print('B _ Show Run ...')class C(A):def show(self):print('C _ Show Run ...')def info(self):# super().info()# A.info(self)print('C - Info run ...')class D(B, C):def show(self):super().show()A.show(self)print('D _ Show Run ...')d = D()
d.show()
d.info()
super对象是基于类的mro顺序来对当前类进行初始化的
基于这个mro顺序可以保证,所有的继承关系的上类,都只执行一次
'''
多继承的初始化问题的解决
'''# 定义一个人类class Person(object):def __init__(self, aaa):print('Person Init ...')self.aaa = aaaclass Father(Person):def __init__(self, name, *args):super(Father, self).__init__(*args)print('Father Init ...')self.name = nameclass Mother(Person):def __init__(self, age, *args):super(Mother, self).__init__(*args)print('Mother Init ...')self.age = ageclass Son(Father, Mother):def __init__(self, gender, name, age, aaa):# 参数二是当前类的实例对象# 参数一是当前类名# 在参数二对象的所属类的mro关系 中找参数一的下一个类进行实始化super(Son, self).__init__(name, age, aaa)print('Son Init ...')self.gender = gender# 测试
# s = Son(1, 'Tom',12,'男')
s = Son('男', 'Tom', 12, 1)
print(s.aaa)
print(s.name)
print(s.age)
print(s.gender)print(Son.__mro__)
'''
这个顺序关系是解释器在执行代码 时,自动确认的我们无法干涉
(,, , , )
'''f = Father('Jack', 2)
print(f.aaa)
print(f.name)
print(Father.__mro__)
mro -> 一个类的继承书写顺序会影响mro顺序

8. 多继承调用指定父类中方法

	父类名.方法()super().方法()

9. 多态

多种形态
程序中的意义:当调用一个方法名的时候,得到的结果不同在一般的面向对象语言中,多态是由继承来实现的但是在python中,python,天生具有多态性鸭子类型: Duck Typing一只鸟如果长的鸭子,叫声像鸭子,那么就认为它就是鸭子
'''
多态
'''# 标准多态class Father(object):def cure(self):print('老中医使用中医治病')class Son(Father):def cure(self):print('小大夫使用中西医结合治病')class Dog(object):def bark(self):print('Won won ...')class AnimalDoctor(object):def cure(self):print('我是个兽医,主要给动物治病,但是也能给人凑合治一下')# 病人类
class Person(object):# 需要一个大夫给他治病def need_doctor(self, doctor):doctor.cure()# 测试
p = Person()p.need_doctor(Father())
p.need_doctor(Son())
# p.need_doctor(Dog())
p.need_doctor(AnimalDoctor())

10. 实例对象属性和实例对象方法

以 对象名.xxx  的形式调用的都是实例的属性或实例的方法
'''
实例属性和实例 方法
'''class Cat(object):def __init__(self, name):# 定义一个实例 属性self.name = name# 定义了一个实例方法def info(self):print(self.name)def show(self):print('Show Run :')self.info()# 测试
tom = Cat('Tom')
# 使用实例属性
print(tom.name)
# 使用实例方法
tom.info()
tom.show()# Python中万物皆对象
# print(Cat.name)
Cat.show()# 结论:
# 为什么类名不能调用 实例 对象属性和实例对象方法呢?
# 因为类对象存在时,不一定有实例对象存在
# 实例属性和实例 方法只能由实例对象调用

​ 实例属性和实例方法只能由实例对象调用

11. 类对象和类属性

类属性可以使用实例对象来引用,但是不能修改
一般情况下:类属性 都只使用 类对象 来调用类对象.类属性
'''
类对象和类属性
'''class ClassRoom(object):# 当定义一个类属性时,相当于这个类中的全局变量# 该类的所有对象都 可以使用该 类属性# 可以在所有的对象间进行数据共享center_kong_tiao = '格力空调'# 实例方法def show(self):print('实例方法中去访问类属性:')print(ClassRoom.center_kong_tiao)cr901 = ClassRoom()
print(cr901.center_kong_tiao)cr902 = ClassRoom()
print(cr902.center_kong_tiao)cr903 = ClassRoom()
print(cr903.center_kong_tiao)# cr901.center_kong_tiao = '海尔空调'
ClassRoom.center_kong_tiao = '海尔空调'
print(cr901.center_kong_tiao)
print(cr902.center_kong_tiao)
print(cr903.center_kong_tiao)cr901.show()

扩展

'''
扩展:属性和方法的保存位置
'''class Cat(object):def __init__(self,name):self.name = nameself.__age = 1def public_method(self):print('公有的对象方法')def __private_method(self):print('私有的对象方法')tom = Cat('Tom')
jack = Cat('Jack')
# __dict__ 是一个魔法属性,用来保存当前对象的所有的成员
print(Cat.__dict__)
print(tom.__dict__)
print(jack.__dict__)tom.public_method()Cat.public_method(tom)
Cat.public_method(jack)def display():print('Display')display()

相关内容

热门资讯

秦始皇出巡五次,究竟是体察民情... 秦始皇出巡五次,究竟是体察民情还是游玩?下面趣历史小编就为大家带来详细的介绍,一起来看看吧!自公元前...
秦始皇究竟是千古一帝?还是千古... 秦始皇究竟是千古一帝?还是千古暴君?下面趣历史小编就为大家带来详细的介绍,一起来看看吧!对于秦始皇的...
张之洞是一个用情比较专一的人 ... 还不知道:张之洞为什么只纳妾不娶妻呢的读者,下面趣历史小编就为大家带来详细介绍,接着往下看吧~张之洞...
最新或2023(历届)安徽高考... 最新或2023(历届)安徽高考体育类第一批征集志愿补录缺额计划专业招生考生在填报前应仔细阅读各校招生...
最新或2023(历届)湖南高考... 最新或2023(历届)湖南高考一本院校投档分数线公布和录取通知书发放时间安排今年湖南本科一批文史类的...