面向对象2
一、面向对象的三大特征
-
继承
-
封装
-
多态
二、继承
-
什么是继承
继承指的是新建类的方法, 新建的类称之为子类或者派生类, 子类继承的类叫做父类,也称之为基类或超类,可以使用base方法查看父类。
class OldboyPeople: school = 'oldboy' def __init__(self, name, age, sex): self.name = name self.age = age self.sex = sex # 老师类: 名字,年龄,性别 class OldboyTeacher(OldboyPeople): # 老师修改分数技能 def change_score(self): print(f'老师[{self.name} 修改分数...]') # 学生类: 名字,年龄,性别 class OldboyStudent(OldboyPeople): # 学生可以选择课程 def choose_course(self, course): print(f'学生[{self.name}]选择课程[{course}]') stu1 = OldboyStudent('小丁丁', 95, 'female') tea1 = OldboyTeacher('tank', 17, 'male') print(stu1.name, stu1.age, stu1.sex) print(tea1.name, tea1.age, tea1.sex)
2. 继承的作用
减少代码冗余
3. 继承背景下对象属性的查找顺序
对象名称空间——类——父类
若查找的属性在子类中存在,不管父类中存不存在,以子类为准
class Foo: def f1(self): print('Foo.f1') def f2(self): print('Foo.f2') self.f1() class Soo(Foo): def f1(self): print('Soo.f1') soo_obj = Soo() soo_obj.f2() 输出 Foo.f2 Soo.f1
三、派生
-
定义 子类继承父类的属性,并派生出新的属性
-
子类派生时重用父类属性的两种方法
-
直接调用父类的init方法
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 OldboyStudent(OldboyPeople): # 课程 def __init__(self, name, age, sex, course): OldboyPeople.__init__(self, name, age, sex) self.course = course def choose_course(self): print(f'学生{self.name}选择课程{self.course}')
2. 使用super()方法,通过‘.’指向父类的名称空间
class OldboyTeacher(OldboyPeople): # 等级, 薪资 def __init__(self, name, age, sex, level, sal): super().__init__(name, age, sex) self.level = level self.sal = sal class OldboyStudent(OldboyPeople): # 课程 def __init__(self, name, age, sex, course): super().__init__(name, age, sex) self.course = course def choose_course(self): print(f'学生{self.name}选择课程{self.course}')
四、新式类与经典类
-
新式类
-
继承object的类都称之为新式类
-
python3中,默认最终继承object,因此都是新式类
2. 经典类
-
python2中,没有继承object的类都是经典类
3. mro()
用来查看当前类的继承顺序
class A: # x = 2 pass class B: # x = 3 pass
# 多继承情况下: class C(A, B): # print('C...') # x = 1 pass # [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>] print(object) print(C.mro())
输出 <class 'object'> [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]
-
菱形继承
-
经典类:深度优先
-
新式类:广度优先
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 # 新式类: F-D-B-E-C-A-object f1 = F() f1.test() # 经典类: F-D-B-A-E-C
五、通过继承添加json模块支持的数据类型
-
直接转成str
import json from datetime import date, datetime #开发者的角度: 直接转成str dict1 = { 'name': 'tank', 'today': str(datetime.today()), 'today2': str(date.today()) } res = json.dumps(dict1) print(res)
2. 修改json源码
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)