类的继承、派生
面向对象的三大特征:
1、继承(组合)
2、封装
3、多态
继承:
1、什么是继承?
继承指的是新建类的方法,新建的类称之为字类或者派生类,
字类继承的类叫做父类,也称之为基类或超类
继承的特征:
字类可以继承父类的属性(特征与属性),并且可以派生出自己的属性(特征与技能)
注意: 在python中,一个子类可以继承多个父类,其他语言只能一个子类继承一个父类.
2、为什么要继承?
继承的目的是为了减少代码冗余(减少重复代码)
3、如何实现继承?
1、首先要确定好谁是子类,谁是父类
2、在定义时,类+(), ()内写父类名,实现继承。
3、在python中,一个子类,可以继承多个父类,
4、用 __ bases __ 方法可以查看对象继承的类
class ParentClass1: # 父类
pass
class ParentClass2:
pass
class SubClass(ParentClass1): # 子类:
pass
class SubClass2(ParentClass1, ParentClass2): # 继承多个父类
pass
4、寻找继承关系
先抽象,再继承
对象是特征与技能的结合体
类是一系列对象相同的特征与技能的结合体
继承是一系列类相同的特征与技能的结合体
查找顺序
在继承背景下,对象属性的查找顺序:
对象查找属性的顺序:对象的名称空间-->对象的类的名称空间-->父类的名称空间-->父类的父类-->...
用查找到的第一个属性,不再继续找,不管父类里边有没有
5、派生:
派生是指子类继承父类的属性,并派生出自己新的属性
子类派生出新的属性,若与父类的属性相同,则以子类的为准.
继承是谁与谁的关系, 指的是类与类的关系,子类与父类是从属关系.
如何在父类的基础上额外添加特征
方法一:
直接通过 父类. _ init __ 调用,此时,__ init __当作普通函数使用,需要传入的参数包括对象和继承的属性。
方式二:
super是一个特殊的类,在子类中调用super()会得到一个特殊的对象,
通过"."指向的是父类的名称空间.
注意: 两种方式不要混合使用.
class OldboyPeople:
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
# 方式一:
# class OldboyTeacher(OldboyPeople):
# # 等级, 薪资
# def __init__(self, name, age, sex, level, sal):
# OldboyPeople.__init__(self, name, age, sex) # 此处用了方式一
# self.level = level
# self.sal = sal
# 方式二:
class OldboyTeacher(OldboyPeople):
# 等级, 薪资
def __init__(self, name, age, sex, level, sal):
super().__init__(name, age, sex) # 此处用了方式二
self.level = level
self.sal = sal
6、新式类与经典类
在python2中,才会有这两种区分
在python3中,所有类都是新式类
新式类:
继承object的类都称为新式类
python3中,所有没指定父类的子类都默认继承object类
经典类:
在python2中,凡是没有继承object的都是经典类
"""""""
在python3:
新式类:
class Foo(object):
pass
class Goo(Foo):
pass
# print(Foo.__bases__) # (<class 'object'>,)
print(Goo.__bases__) # (<class 'object'>,)
7、mro():
mro(): 属于object--> type的函数, 用来查看当前类的继承顺序, 在多继承的情况下.
class A:
# x = 2
pass
class B:
# x = 3
pass
# 多继承情况下:
class C(A, B):
# print('C...')
# x = 1
pass
print(object)
print(C.mro())
打印结果:
# [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]
8、钻石继承(菱形继承):
在多层继承的情况下会形成钻石继承
经典类: 深度优先
新式类: 广度优先
# 验证
class A:
# 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
f1 = F()
f1.test()
# 新式类: F-D-B-E-C-A-object
# 经典类: F-D-B-A-E-C
9、通过继承实现修改json模块数据类型:
import json
from datetime import date, datetime
class MyJson(json.JSONEncoder):
def default(self, o):
# 子类派生的功能
# 判断o是否式datetime的一个实例
if isinstance(o, datetime):
return o.strftime('%Y-%m-%d %X')
elif isinstance(o, date):
return o.strftime('%Y-%m-%d')
else:
# 继承父类的default方法的功能
return super().default(self, o)
dict1 = {
'name': 'tank',
'today': datetime.today(),
'today2': date.today()
}
res = json.dumps(dict1, cls=MyJson) # cls=None,默认指向的是原json的JSONEncoder
print(res)