实践是检验真理的唯一标准:拷贝到pycharm一试便知。
类的特性:
1、继承:子类继承父类,就拥有了父类的所有方法和属性(私有方法和属性除外)
2、封装:隐藏内部的实现,对外公开接口或者方法
3、多态:一个事物有多种形态
一、继承
1、继承的写法
class Test02(Test01):
2、子类调用父类的方法
1、调用实例方法
self.方法名称()
2、初始化方法
1、子类没有写初始化方法:在调用父类方法的时候,会自动调用父类的初始化方法
2、子类有初始化方法,就会调用自己的初始化方法,不会自动调用父类的初始化方法,除非手动super().init()
3、super().init() 与 父类().init()区别
1、手动调用父类的初始化方法:super().init()
2、调用初始化方法的时候 super().init()不会存在重复调用父类初始化方法的问题
3、调用初始化方法的时候通过父类 ClassFu().init()会重复调用父类的初始化话方法
4、在调用普通方法的时候没有区别
5、super().init()调用初始化方法,实例属性才能被子类继承下来
6、ClassFu().init()调用初始化方法,实例属性未继承
4、子类调父类的普通方法(通过类实例调用(类实例、self))
1、父类与子类有同名的方法:通过子类的实例去调用,优先调用自己的方法
2、子类没有定义,父类定义了某个方法,调用的时候先查询子类是否有该方法,如果没有再查询父类
按继承顺序一次往上查询,查到就执行,查不到就报错。
3、方法的查询顺序(子类 -->父类-->爸爸的爸爸........一直查到object(基类))
5、子类(通过super())调父类的普通方法。
1、跳过子类,直接从父类去找对应的方法,按照继承顺序查找(从左往右),
方法的查询顺序(父类-->爸爸的爸爸........一直查到object(基类))
3、继承的使用场景
1、子类需要使用父类的方法和属性
2、重写父类方法:
在子类中,与父类同名方法内不添加 super().父类同名方
3、在父类方法上做拓展(类似装饰器):
在子类中,与父类同名方法内添加 super().父类同名方
# 父类
import time
class ClassFu: # 相当于 ==> class Test01(object):
name = "老王"
def __init__(self):
print("父类的初始化方法__init__")
self.age = 20
def test_01(self):
time.sleep(2)
print("父类ClassFu的方法test_01")
def test_02(self):
print("父类ClassFu的方法test_02")
def test_04(self):
print("父类ClassFu的方法test_04")
# 1、子类没有写初始化方法:在调用父类方法的时候,会自动调用父类的初始化方法
class ClassZi01(ClassFu):
pass
# 2、子类有初始化方法,就会调用自己的初始化方法,不会自动调用父类的初始化方法
class ClassZi02(ClassFu):
def __init__(self):
print("子类ClassZi02的初始化方法__init__")
# 3、super().__init__() 与 父类().__init__()区别
class ClassZi03(ClassFu):
def __init__(self):
print("子类ClassZi03的初始化方法__init__")
# 1、手动调用父类的初始化方法:super().__init__()
# 不会存在重复调用父类初始化方法
# 实例属性被子类继承
super().__init__()
# 3、super().__init__() 与 父类().__init__()区别
class ClassZi04(ClassFu):
def __init__(self):
print("子类ClassZi04的初始化方法__init__")
# 会重复调用父类的初始化话方法
# 实例属性未继承
ClassFu().__init__()
# 4、子类调父类的普通方法(通过类实例调用(类实例、self))
# 5、子类(通过super())调父类的普通方法。
class ClassZi05(ClassFu):
def __init__(self):
print("子类ClassZi05的初始化方法__init__")
super().__init__()
def test_01(self):
print("子类ClassZi05的方法test_01")
def test_03(self):
print("子类ClassZi05的方法test_03")
super().test_01() # 用super() 子类有,也不用,从父类找
self.test_04() # 子类有,用子类,不用父类
def test_04(self):
print("子类ClassZi05的方法test_04")
# 3、继承的拓展 和 重写
# 子类 ClassZi06
class ClassZi06(ClassFu):
def __init__(self):
print("子类ClassZi06的初始化方法__init__")
super().__init__()
def test_01(self):
print("子类ClassZi06的方法test_01")
start_time = time.time()
super().test_01() # 不加这行是重写父类方法,加上是拓展父类方法
end_time = time.time()
return end_time - start_time
if __name__ == '__main__':
# 2、子类调用父类的方法 ####################################################################################
"""2、初始化方法"""
# 1、子类没有写初始化方法:会自动调用父类的初始化方法
cl_z_1 = ClassZi01()
# 父类的初始化方法__init__
print('cl_z_1.age:', cl_z_1.age) # 能调父类的实例属性
# cl_z_2.age: 20
# 2、子类有初始化方法:就只会调用自己的初始化方法,不掉父类...
cl_z_2 = ClassZi02()
# 子类ClassZi02的初始化方法__init__
# print('cl_z_2.age:', cl_z_2.age) # 不能调父类的实例属性,需super().__init__()
# # AttributeError: 'ClassZi02' object has no attribute 'age'
"""3、super().__init__() 与 父类().__init__()区别"""
print('cl_z_3 ==================================================================================')
# 1、手动调用父类的初始化方法:super().__init__()
# 2、调用初始化方法的时候super().__init__()不会存在重复调用父类初始化方法的问题
cl_z_3 = ClassZi03()
# 子类ClassZi03的初始化方法__init__
# 父类的初始化方法__init__
# 3、调用初始化方法的时候ClassFu().__init__()会重复调用父类的初始化话方法
cl_z_4 = ClassZi04()
# 子类ClassZi04的初始化方法__init__
# 父类的初始化方法__init__
# 父类的初始化方法__init__
# 4、在调用普通方法的时候没有区别
print('执行:cl_z_3.test_01()、cl_z_3.test_01():')
cl_z_3.test_01()
# 父类ClassFu的方法test_01
cl_z_4.test_01()
# 父类ClassFu的方法test_01
# 5、super().__init__()调用初始化方法,实例属性才能被子类继承下来
print('cl_z_3.__dict__:', cl_z_3.__dict__)
# cl_z_3.__dict__: {'age': 20}
print('cl_z_3.age:', cl_z_3.age)
# cl_z_3.age: 20
# 6、ClassFu().__init__()调用初始化方法,实例属性未继承
print('cl_z_4.__dict__:', cl_z_4.__dict__)
# cl_z_4.__dict__: {}
# print('cl_z_4.age:', cl_z_4.age) # 打印报错
# # AttributeError: 'ClassZi04' object has no attribute 'age'
# 父类的类属性 子类都能访问,无论是否有初始化方法、是否调用父类初始化方法
print('ClassZi01.name:', ClassZi01.name)
print('ClassZi02.name:', ClassZi02.name)
print('ClassZi03.name:', ClassZi03.name)
print('ClassZi04.name:', ClassZi04.name)
# ClassZi01.name: 老王
# ClassZi02.name: 老王
# ClassZi03.name: 老王
# ClassZi04.name: 老王
"""4、子类调父类的普通方法(通过类实例调用(类实例、self))"""
print('cl_z_5 ==================================================================================')
# 创建子类实例对象
cl_z_5 = ClassZi05()
# 子类ClassZi05的初始化方法__init__
# 父类的初始化方法__init__
# 1、父类与子类有同名的方法:通过子类的实例去调用,优先调用自己的方法
cl_z_5.test_01()
# 子类ClassZi05的方法test_01
# 2、子类没有定义,父类定义了某个方法,调用的时候先查询子类是否有该方法,如果没有再查询父类
cl_z_5.test_02()
# 父类ClassFu的方法test_02
"""5、子类(通过super())调父类的普通方法。"""
# 1、跳过子类直接从父类去找对应的方法,按照继承顺序查找(从左往右)
cl_z_5.test_03()
# 子类ClassZi05的方法test_03
# 父类ClassFu的方法test_01
# 子类ClassZi05的方法test_04
# 3、继承的使用场景 ######################################################################################
print('cl_z_6 ==================================================================================')
cl_z_6 = ClassZi06()
# 子类ClassZi06的初始化方法__init__
# 父类的初始化方法__init__
print(cl_z_6.test_01())
# 子类ClassZi06的方法test_01
# 父类ClassFu的方法test_01
# 2.001312255859375
二、多继承
1、继承多个父类【掌握】
1、方法的查询顺序(子类 -->父类-->........object(基类))
2、其他的同单继承
# """1、继承多个父类【掌握】"""
class Test01:
def test_01(self):
print("Test01类的test_01")
class Test02:
def test_02(self):
print("Test02类的test_02")
class Test03:
def test_03(self):
print("Test03类的test_03")
class Test04(Test01, Test02, Test03):
def test_04(self):
print("Test04类的test_04")
if __name__ == '__main__':
cl4 = Test04()
cl4.test_01()
# Test01类的test_01
cl4.test_03()
# Test03类的test_03
2、多重继承【了解】
1、多重继承会存在继承顺序错乱,导致python无法计算MRO表(继承关系图谱)
2、尽量不要用多重继承
# """2、多重继承【了解】"""
class Test01:
def test_02(self):
print("Test01类的test_01")
class Test02(Test01):
def test_01(self):
print("Test02类的test_02")
class Test03(Test01, Test02):
def test_03(self):
print("Test03类的test_03")
if __name__ == '__main__':
cl3 = Test03()
cl3.test_01()
# TypeError: Cannot create a consistent method resolution
# order (MRO) for bases Test01, Test02
三、多态【了解】
不好用,通常不这么用,通常直接一个类建立多个不同方法更方便。
例如场景:公司的方法已经用了很久,不好方便去改,就新建一个方法传入不同的类去调用他们相同的方法。
# """三、多态【了解】"""
class Dog:
def eating(self):
print("狗子在吃东西")
class Cat:
def eating(self):
print("小猫在吃东西")
def animal(obj):
cl = obj()
cl.eating()
if __name__ == '__main__':
animal(Cat)
animal(Dog)
# 小猫在吃东西
# 狗子在吃东西
。
欢迎来到testingpai.com!
注册 关于