1010

那年仲夏 提交于 2019-12-01 02:58:30

面向对象之继承

面向对象的三大特性:

  1. 继承 (组合)
  2. 封装
  3. 多态

一.什么是继承

继承指的是新建类的方式,新建的类称之为子类或者派生类

子类继承的类叫做父类,也称之为基类或超类.

继承的特征:

子类可以继承父类的属性(特征与技能),子类可以派生出自己的属性(特征与技能)

注意:在python中一个子类可以继承多个父类

二.为什么要继承

继承的目的是为了减少代码的冗余(减少重复代码)

三.如何实现继承

  1. 首先要确定好谁是子类,谁是父类
  2. 在定义时,子类名 + ( ),()内写父类,实现继承

1.__bases__查看类的父类

__bases__是类的属性,用来查看当前类的父类

class fu:     pass class zi(fu):     pass print(zi.__bases__) #  (<class '__main__.fu'>,) #  子类可以继承多个父类 class ye:     pass class sun(fu,ye):     pass print(sun.__bases__) # (<class '__main__.fu'>, <class '__main__.ye'>)

2.寻找继承关系

想要寻找继承关系,就要'先抽象,再继承'

什么是抽象

抽象指的是抽取相似的部分,称之为抽象

也就是获得对象对应的相似的将之聚合为一类.

类似于人狗猪同属于哺乳动物类,爬行动物与哺乳动物同属于动物类

继承的关系

对象是特征与继承的结合体

类是一系列对象相同的特征与技能的结合体

继承是一系列类相同特征与技能的结合体

# 老师类 class teacher:     school = 'oldboy'     def __init__(self,name,age):         self.name = name         self.age = age     def change(self):         print(f'老师{self.name}更改分数')  # 学生类 class student:     school = 'oldboy'     def __init__(self,name,age):         self.name =name         self.age = age     def choise(self):         print(f'用户{self.name}可以选课')  t1 = teacher('数学',55) s1 = student('aaa',18)  '''使用继承思想减少重复代码''' '''使用继承方法''' # 老男孩的老师学生基类 class OldPeople:     school = 'oldboy'     def __init__(self,name,age):         self.name = name         self.age = age  class teacher(OldPeople):     def change(self):         print(f'老师{self.name}更改分数')  class student(OldPeople):     def choise(self):         print(f'用户{self.name}可以选课')  t1 = teacher('数学',55) s1 = student('aaa',18) print(t1.school,t1.age)     # oldboy 55 print(s1.school,s1.name)    # oldboy aaa 

3.对象属性的查找顺序

对象==> 子类 ==> 父类 ==> object(基类)

在继承背景下,对象属性的查找顺序:

​ 1.对象查找属性会先从对象的名称空间中查找

​ 2.若对象没有,则会去类里面找

​ 3.若当前类是子类,且没有对象找的属性,会去父类中查找

注意:对象查找属性,若子类有,不管父类有没有,以子类为准

.__dict__查看对象的名称空间

.__class__对象的属性,查看当前对象的类

验证对象属性的查找顺序

class foo:     def f1 (self):         print('foo.f1')      def f2(self):         print('f00.f2')         self.f1()  class soo(foo):     def f1(self):         print('s00.f1')  s = soo() s.f2() # f00.f2 # s00.f1

4.派生

什么是派生:

派生指的是子类继承父类的属性,并且可以派生出新的属性

子类派生出新的属性,若与父类的属性相同,以子类为准

继承是谁与谁的关系,指的是类与类的关系,子类与父类是从属关系

5.重用父类

子类派生新的属性,并重用父类的属性

'''学生与老师的信息表有相同的姓名,年龄还有不同的等级(老师)与成绩(学生),如果想要使用继承解决代冗余问题''' '''使用继承方法''' # 老师类 class teacher:     school = 'oldboy'     def __init__(self,name,age,level):         self.name = name         self.age = age         self.level = level  # 老师有等级     def change(self):         print(f'老师{self.name}更改分数')  # 学生类 class student:     school = 'oldboy'     def __init__(self,name,age,grade):         self.name =name         self.age = age         self.grade = grade  # 学生有成绩     def choise(self):         print(f'用户{self.name}可以选课')  t1 = teacher('数学',55,100) s1 = student('aaa',18,'A') 

方式一:直接通过调用父类.__init____init__当做普通函数使用,传入对象,与继承的属性.

'''重用''' # 老男孩的老师学生基类 class OldPeople:     school = 'oldboy'     def __init__(self,name,age):         self.name = name         self.age = age  # 老师类 class teacher(OldPeople):     def __init__(self,name,age,level):         #  定义的所有需要的变量         OldPeople.__init__(self,name,age)         #  将父类中需要的参数调用到子类中         self.level = level     def change(self):         print(f'老师{self.name}更改分数')  class student(OldPeople):     def __init__(self,name,age,grade):         OldPeople.__init__(self,name,age)         self.grade = grade     def choise(self):         print(f'用户{self.name}可以选课')  t1 = teacher('数学',55,100) s1 = student('aaa',18,'A') print(t1.school,t1.age,t1.level)     # oldboy 55 100 print(s1.school,s1.name,s1.grade)    # oldboy aaa A

方式二: 使用特殊类super(),在子类调用super()会得到一个特殊的对象,而这对象指向的是父类的名称空间,拿到__init__

'''重用''' # 老男孩的老师学生基类 class OldPeople:     school = 'oldboy'     def __init__(self,name,age):         self.name = name         self.age = age  # 老师类 class teacher(OldPeople):     def __init__(self,name,age,level):         #  定义的所有需要的变量         super().__init__(name,age) #  这里super就代表self ,所以使用super,不需要使用self         self.level = level     def change(self):         print(f'老师{self.name}更改分数')  class student(OldPeople):     def __init__(self,name,age,grade):         super().__init__(name,age)         self.grade = grade     def choise(self):         print(f'用户{self.name}可以选课')  t1 = teacher('数学',55,100) s1 = student('aaa',18,'A') print(t1.school,t1.age,t1.level)     # oldboy 55 100 print(s1.school,s1.name,s1.grade)    # oldboy aaa A

两种方式不要混合使用

6.经典类与新式类

在python2中,才会有新式类和经典类之分

在python3中,所有的类都是新式类

新式类

继承object的类都称之为新式类

python3中子类不继承自定义的类,所有的的类默认继承object

经典类

在python2中,凡是没有继承object的类都是经典类

mro()

python中内置的函数,用来查看当前类的继承顺序,在多继承的情况下

class a:     x=3     pass  class b:     x = 2     pass  class c(a,b):     pass  print(c.x)  # 3 # 类继承时从左到右查找,从对象到子类到父类最后object print(c.mro()) # [<class '__main__.c'>, <class '__main__.a'>, <class '__main__.b'>, <class 'object'>]

7.钻石继承的查找顺序

如果子类继承自两个单独的超类,而那两个超类又继承自同一个公共基类,那么就构成了钻石继承体系。这种继承体系很像竖立的菱形,也称作菱形继承。

​ 在多继承的情况下形成的钻石继承(继承顺序的不一致)

经典类: 深度优先

新式类:广度优先

8.修改json数据格式品种

from datetime import date,datetime import json '''datetime模块化时间 json是不能序列化的,报错解决'''  # 方式一 开发者角度:使用str强制准换  dic = {     'name':'tank',     'today':str(datetime.today()),     'today2':str(date.today()) } res = json.dumps(dic) print(res)   # 方式二 开源者角度:修改json源码 class MyJson(json.JSONEncoder):     # 继承父类的属性,派生出自己的属性,继承json.JSONEncoder的属性     # 继承的是可序列化的数据类型     def default(self, o):     # default 方法可以return 出去可序列化的类型,覆盖父类的default         if isinstance(o,datetime): # python内置的函数,可以传入两个参数,判断参数一是否是参数二的一个实例 # 传入dic 字典,字典的每一个属性就会传入到o中,然后判断o是否datetime的一个实例             return o.strftime('%Y-%m-%d %X')         # strftime() 函数接收以时间元组,并返回以可读字符串表示的当地时间         elif isinstance(o,date):         # 继续判断o是否是data的一个实例             return o.strftime('%Y-%m-%d')          else:         # 如果不是以上两个类的,就使用父类的方法             return super().default(self,o)             # super()指向的是父类,这里使用父类的default方法   dic = {     'name':'tank',     'today':datetime.today(),     'today2':date.today() }  res = json.dumps(dic,cls=MyJson ) # cls 默认指向原json类中JSONEncoder,现在将其指向自己写的MyJson类中 print(res) # {"name": "tank", "today": "2019-10-10 17:58:44", "today2": "2019-10-10"} 
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!