继承课堂小结day20

昨日回顾:

  1. 面向对象编程:

    核心是‘对象’,对象指的是特征与技能的结合体。

    基于该编程思想编写程序,就好比在创造世界,一种上帝的思维模式

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

    定义类时发生的事情:

    1. 会产生一个空的名称空间

      1. 会把类内部所有名字扔进名称空间中。
    2. 会执行类内部的代码。

    调用类时发生的事情:

    1. 会产生一个空的对象

      1. 会自动触发__init__
      2. 会将对象与括号内的参数一同传给__init__.

    注意:调用类的过程称之为类的实例化,产生的对象称之为类的一个实例

  3. 对象:

    对象的属性查找顺序:
    对象查找类的属性:

    1.会先去对象的名称空间查找

     2. 若对象没有则会去类的名称空间查找
  4. 对象的绑定方法特殊之处

    1. 由类来调用类内部的函数,该函数只是一个普通的函数,函数需要接收几个参数就得传几个参数。
    2. 由对象来调用类内部的函数,该函数称之为对象的绑定方法,会将不同的对象绑定给不同的方法,特殊之处是会将对象当作第一个参数传给该方法。
  5. 一切皆对象

    在python中,一切皆对象。

    指的是通过type()查看,若返回的是 的都是对象。

    例如:python的8大数据类型。

继承初体验

   # 父类
class ParentClass1:
       pass

   class ParenClass2:
       pass
   
   #子类
   class SubClass1(ParentClass1):
       pass
   
   #继承多个父类
   class SubClass2(ParenClass1,ParentClass2):
       pass
   
   #查看继承的父类:__bases__,是类的属性,用来查找当前类的父亲。
   print(SubClass1.__bases__) #(<class'__main__.ParentClass1'>,)
   print(SubClass2.__bases__) #(<class'__main__.ParentClass1'>,<class'__main.ParentClass2'>)

# 寻找继承关系

如何寻找继承关系:

​ 先抽象,再继承

什么是抽象?

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

—先抽象(抽象思想)

​ 奥巴马——人类——动物类

​ 麦兜——猪类——动物类

​ 小丁丁——狗类——动物类

​ 抽象定义动物类,称之为父类。

​ 特征:

​ 眼睛,鼻子。。

​ 技能:

​ 吃,喝,拉,撒。。

—再继承(在程序中):

​ 奥巴马对象——调用人类——继承动物类

​ 麦兜对象——调用猪类——继承动物类

​ 小丁丁对象——调用狗类——继承动物类

继承的关系:

​ 对象是特征与技能的结合体。

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

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

老男孩选课系统:

# 父类:
'''
抽象:
 school
 __init__(self,name,age,sex)
'''
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 = OldboyStudent('tank',17,'male')

print(stu1.name,stu1.age,stu1.sex)
print(tea1.name,tea1.age,tea1.sex)
    

# 继承背景下对属性查找顺序

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

1. 对象查找属性会先从对象的名称空间中查找
        2. 若对象没有,则会去类里面找
        3. 若当前类是子类,并且没有对象找的属性,会去父类中查找

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

# 父类
class OldboyPeople:
    school = 'oldboy'
    
    def __init__(self,name,age,sex)
     self.name = name
        self.name = age
        self.sex = sex
        
#子类
class OldboyTeacher(OldboyPeople):
    def change_score(self):
        print(f'老师[{self.name} 修改分数])

              
tea1 = OldboyTeacher('tank',17,'male')
print(tea1.school)
              
             
# 查看对象名称空间
print(tea1.__dict__)
__class__:对象的属性,查看当前对象的类.
#查看子类名称空间
print(tea1.__class__.__dict__)
#查看父类名称空间
print(tea1.__class__.__bases__[0].__dict__)
              
              
#验证
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_boj = Soo()
soo_boj.f2()# Foo.f2 Soo.f1

# 派生

什么是派生?

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

​ 子类派生出新的属性,若与父类的属性相同,则以子类得到为准。

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

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

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):
        self.name = name
        self.age = age
        self.sex = sex
        self.level = level
        self.sal = sal


class OldboyStudent(OldboyPeople):
     # 课程
     def __init__(self,name, age, sex, course):
         self.name = name
         self.age = age
         self.sex = sex
         self.course = course

问题: 子类继承父类的__init__毫无意义.

解决方式有两种:

​ 方式一:

​ 直接通过 父类.(调用)__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 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}')
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):
         super().__init_-(name,age,sex)
            self.level = level
            self.sal = sal

class OldboyStudent(OldboyPeople):
    def __init__(self,name,age,sex,course):
        super().__init__(self,name,age,sex)
     self.course = course
        
    def choose_course(self):
        print(f'学生{self.name}选择课程{self.course}')
        
tea1 = OldboyTeacher('tank',17,'male',9,'3.0')
stu1 = OldboyStudent('zzx',23,'male','python')
print(tea1.name,tea1.level)
print(stu1.name,stu1.course)
stu1.choose_course()

# 新式类与经典类

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

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

新式类:

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

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

经典类:

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

mor():属于object——》type的函数,用来查看当前类的继承顺序,在多继承的情况下。

# 钻石继承

钻石继承也可以称之为菱形继承

(了解 面试)

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

    经典类:

​ 深度优先

​ 新式类:

​ 广度优先

# 通过继承实现修改json模块数据类型

import json
from datetime import date, datetime

print(json.JSONEncoder)
print(datetime.today())  # 当前时间
print(date.today())  # 当前日期

# 开发者的角度: 直接转成str
# dict1 = {
#     'name': 'tank',
#     'today': str(datetime.today()),
#     'today2': str(date.today())
# }
#
# res = json.dumps(dict1)
# print(res)


# isinstance:
# python内置的函数,可以传两个参数,判断参数一是否式参数二的一个实例.

# 开源者的角度: 修改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)

猜你喜欢

转载自www.cnblogs.com/shin09/p/11650290.html