什么是继承?
继承是一种新建类的方式,新建的类称之为子类或派生类,继承的父类称之为基类或超类
在python中,一个子集可以继承多个父类。(面试可能会问)
在其他语言中,一个子集只能继承一个父类
继承的作用?
减少代码的冗余
如何实现继承?
1)先确定谁是父类,谁是子类
2)在定义类子类时,子类名(父类名)
#
# class Father1:
# s = 1
#
# class Father2:
# s = 10
#
# class Sub(Father1, Father2):
# s = 20
#
# print(Sub.__bases__)
# print(Sub.x)
如何寻找继承关系
先抽象,在继承
抽取对象中间相似的部分,总结出类
抽取类之间相似的部分,总结出父类
# class oldbayPeople:
# school = 'oldboy'
# country = 'China'
#
# def __init__(self, name, age, sex):
# self.name = name
# self.age = age
# self.sex = sex
#
# class Teacher(oldbayPeople):
# def change_score(self):
# print(f'老师{self.name}在修改分数')
#
# class Student(oldbayPeople):
# def learning(self):
# print(f'学生{self.name}在学习')
#
# t1 = oldbayPeople('jinyi', 22, 'male')
# s1 = oldbayPeople('wanglu', 19, 'female')
# print(s1.name)
# print(t1.name)
# s2 = Student('wanglu', 19, 'female')
# print(s2.name)
在继承背景下对象属性的查找顺序
程序的执行是由上到下,父类必须定义在子集的上方
在继承背景下,对象属性的查找顺序
1、先从对象自己的名称空间里找
2、对象中没有,从子集的名称空间中查找
3、子集中没有,从父类的名称空间中查找,还没有就报错
派生
派生指的是子类继承父类的属性与方法,并且派生出自己独有的属性与方法
若子类中的方法名与父类相同,优先用子类的
# 父类
# class Foo:
# def f1(self):
# print('from Foo.f1...')
#
# def f2(self):
# print('from Foo.f2...')
# 子类
# class Bar(Foo):
# def f1(self):
# print('from Bar.f1...')
# def func(self):
# print('from Bar.func...')
#
#
# obj = Bar()
# print(obj.f1())
# print(obj.f2())
子类继承父类并重用父类的属性与方法
子类继承父类,派生出自己的属性与方法, 并且重用父类的属性与方法
# 问题:子类重写父类的__init__导致代码更加冗余
class Oldboy:
school = 'oldbay'
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
class Teacher(Oldboy):
def __init__(self, name, age, sex, sal):
self.name = name
self.age = age
self.sex = sex
self.sal = sal
t1 = Teacher('wanglu', 19, 'famale', 18000)
print(t1.name)
'''
解决方法:
两种方式:
1、直接引用父类的__init__为其传参,并添加子类属性
2、通过super来指向父类的属性。
-super()是有个特殊的类,调用super得到一个对象
该对象指向父类的名称空间
注意:使用哪一种都可以,但不能两种方式混合使用
'''
# 方式一
# class Oldboy:
# school = 'oldbay'
#
# def __init__(self, name, age, sex):
# self.name = name
# self.age = age
# self.sex = sex
#
# class Teacher(Oldboy):
# def __init__(self, name, age, sex, sal):
# Oldboy.__init__(self, name, age, sex)
# self.sal = sal
#
# t1 = Teacher('wanglu', 19, 'famale', 18000)
# print(t1.name, t1.sex)
class Oldboy:
school = 'oldbay'
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
class Teacher(Oldboy):
def __init__(self, name, age, sex, sal):
super().__init__(name, age, sex)
self.sal = sal
t2 = Teacher('wanglu', 19, 'famale', 18000)
print(t1.sex, t1.sal)
经典类与新式类:(了解)
工作中遇不到
面试可能会问
新式类:
凡是继承object的类或子孙类都是新式类。
在python3中所有的类都是默认继承object。
经典类:
在python2中才会有经典类与新式类之分。
在python2中,凡是没有继承object的类,都是经典类
'''
多继承情况下造成 “钻石继承”
mro的查找顺序:
- 新式类:
- 广度优先
- 经典类:
- 深度优先
面试注意细节:
- 遇到一个技术 知道是什么,但是不会用,一定要贬低这个技术,觉得很简单,让面试官误以为你很会。
- 遇到一个技术,不知道是什么,要说我见过,但是忘记怎么用了,我博客里面,回头找一下就行了。
'''
# 了解:
# 新式类:
class A(object):
# def test(self):
# print('from A')
pass
class B(A):
# def test(self):
# print('from B')
pass
class C(A):
# def test(self):
# print('from C')
pass
class D(B):
# def test(self):
# print('from D')
pass
class E(C):
# def test(self):
# print('from E')
pass
class F(D, E):
# def test(self):
# print('from F')
pass
# F-->D-->B-->E-->C-->A-->object
# print(F.mro())
obj = F()
obj.test()