zoukankan      html  css  js  c++  java
  • 上海 day21 -- 面向对象三大特征----继承

    目  录

        2w + h、抽象派生覆盖子类访问父类

        不同类之间的访问

        多继承之菱形继承、新式类和经典类、属性访问顺序

     

     前言:我们首先基于一个目的来讲继承 -- 就是代码的复用性,减少代码的冗余。

       基于这个目的我们引出两种方式—— 继承和组合。

    一、继承

    什么是继承?

    继承是一种关系,可以理解为是‘什么是什么的关系’,在程序中就是类与类之间的关系。例如 a 类继承了b类,那么a类就可以调用b类的方法和属性。

    为什么要用继承?

    因为继承的一方可以直接使用被调用一方的属性和方法,其目的是重用已经有的代码,提高代码的复用性。

    怎么用继承?

    继承的语法:class 类名称(父类的名称):

    class 类名称(父类的名称):
        类的内容 
        
    #在python中 一个子类可以同时继承多个父类 

    二、抽象

    什么是抽象?

    抽象就是将多个类之间相同的地方或有共同特征的属性抽取出来,组成一个新的共同的父类,这个过程就叫做抽象。

    抽象的作用:

    就是帮助我们更好的使用继承。

    如何正确的使用继承呢?

    1、先抽象在继承

    2、继承一个现存的类,修改或扩展该类的功能

    属性的查找顺序?

    class A:
        text = "haha"
    
    class B(A):
        text = "heihei"
        pass
    
    b = B()
    b.text = "xixi"
    
    print(b.text)

    对象自己的 - > 所在类中 -> 找父类 - >父类的父类 ->Object

    其中Object类中最基本的类,python3 中的类都是由Object 派生出来的,这些类也称为是‘新生类’,后面会介绍!

    三、派生

    什么是派生?

    就是原来的子类发展出于父类不同的功能就叫做‘派生’,这样的类也叫做‘派生类’。

    因为对于一个子类来说会生成自己独有的功能,会与父类的代码有区别,所以这类子类统称为‘派生类’,

    派生类的实质就是子类,可理解成不同的叫法。

    四、覆盖

    什么是覆盖?

    覆盖也叫做‘重写’,overwrite。

    当子类中出现与父类相同的方法或属性时,父类中的这些方法和属性会被覆盖赋值,这种现象叫做‘覆盖’。

    覆盖的实质是因为属性的查找顺序决定的:先从子类自身找  ——》父类中找 ——》Object中找,

    当父类中的属性和子类名字一样时,子类的属性或方法名字会覆盖父类的,就像是变量的重新赋值一样。

    '''
    派生与覆盖
    '''
    class Person:
        def say_hi(self):
            print('hello')
    
    class Student(Person):
        def say_hi(self):
            print('hello word!')
    # 覆盖:子类有和父类相同的方法名字 say_hi
    s1 = Student()
    s1.say_hi()  # hello word!

     

    五、子类中访问父类的内容   *****(重点内容)

    语法如下:

    方式1:
    super(当前类名称,self).你要调的父类的属性或方法
    方式2:
    super().你要调的父类的属性或方法
    方式3:
    类名称.你要调的父类的属性或方法(self)  
    #方式3与继承无关 

    代码示例:

    class Person:
        text = 'from CQUPT'
        def say_hi(self):
            print('hello')
    
    class Man(Person):
        def show_info(self):
            # 方式一:子类访问父类   方法:   super(子类名,self对象).父类中的方法
            print(super(Man,self).text)
            super(Man,self).say_hi()
    
    m1 = Man()  # 对象的创建
    m1.show_info() # 调用方法
    方式1
    class Man:
        res = '老九门串串'
        def say_some(self):
            print('欢迎光临!')
    
    class Student(Man):
        def say_no(self):
            print('请记住下面两句话')
            # 方式2:子类访问父类  方法:  super().父类的属性或方法
            print(super().res)
            super().say_some()
    
    stu1 = Student()  # 创建对象
    stu1.say_no()  # 对象调用自身方法
    方式2
    class Women:
        res = '一直bb'
        def say_some(self):
            print('真烦人')
    
    class Woman(Women):
        def say_no(self):
            # 方式3:子类访问父类   直接用父类调用父类自己的属性和方法  父类名称.方法()或父类名称.属性
            print(Women.res)
            Women.say_some(self)  # 注意:父类调用子类的方法要加 self对象,否则报错
            print('唉算了')
    
    w1 = Woman()  #创建对象
    w1.say_no()
    方式3

     

    强调在强调:****** (重点)

    当你继承一个现有的类,并且你覆盖了父类的init方法时,必须在初始化方法的第一行调用父类的初始化方法,并传入父类所需的参数

    练习:

    实现一个可以限制元素类型的容器 (字典,列表,元组,集合,字符串)

    """
    需求 实现一个能够限制元素类型的列表类
    
    """
    class MyList(list):
        def __init__(self,element_type):
            super().__init__() # 调用父类的初始化方法 来完成基本的初始化
            self.element_type = element_type
    
        def append(self, object):
            """
            :param object: 是要存储的元素
            :return: 没有
            """
            if type(object) == self.element_type:
                #我们需要在这里访问父类的append函数来完成真正的存储操作
                super(MyList,self).append(object)
            else:
                print("sorry sir, you element type not is %s" % self.element_type)
    
    
    # 创建是指定要存储的元素类型
    m = MyList(int)
    # 当你有需求,是需要在创建对象时 干点什么事儿  那就该想到初始化方法
    
    m.append(1)
    print(m[0])
    m.append("121212")

    此处知识点也可以引用为一个问题:

    为什么要在初始化方法中调用父类的初始化方法?

    六、组合

    组合的引出?

    上面提出子类访问父类中内容的方法,那么不是父子关系或者说两个类之间没有什么关联,这两个类要怎么访问(调用)对方的功能呢?

    因此提出‘组合’的方法。

    什么是组合?

    组合也是一种关系,它描述的是两个对象之间‘什么有什么的关系’,

    例如:学生有手机—用来打电话,‘学生’、‘手机’是两个不同的对象,‘学生’ 使用‘手机’打电话的功能!

    因此我们可以总结说:组合,在程序中就是将一个对象作为另一个对象的属性!

    代码示例:

    class Phone:
        def __init__(self,price,kind,color):
            self.price = price
            self.kind = kind
            self.color = color
    
        def call(self):
            print("正在呼叫XXXX;")
    
        def send_message(self):
            print("正在发送短信....")
    
    
    class Student:
        def __init__(self,name,gender,phone):
            self.name = name
            self.gender = gender
            self.phone = phone
    
        def show_info(self):
            print("name:%s gender:%s" % (self.name,self.gender))
    
    phone = Phone(1000,"apple","red")
    
    stu1 = Student("rose","male",phone)
    stu1.phone.call()

    组合的作用?

    重用已有的代码,提高代码的复用性

    如何区分何时使用继承,什么时候使用组合?

    当两个类之间有相同和相似的特征时,或有‘什么是什么的关系’时,考虑用继承!

    当两个类之间没有什么关联,只是普通的想要使用对方的功能时,考虑用组合!

    另外:组合与继承相比耦合度更低!

    七、多继承

    在Python中对象明确是可以继承多个类的,即支持多继承!

    菱形继承:

    引入两个概念:新式类和经典类

     

     Python3 中的类都是直接或间接的继承了Objest类

    新式类:显示或隐式的继承自Object类就叫做新式类,Python3 中的类都是新式类

    经典类:不是Object 的子类,就是经典类。经典类只在Python2 中出现

    菱形继承的查找顺序?

    当出现菱形继承时,新式类 先深度,遇到有共同父类时在广度查找;

                                    经典类就是深度优先,深度查找完在广度查找!

  • 相关阅读:
    欧拉回路的判断(hdu1878)其一
    最长公共子序列(不是子串)hdu1159
    线段树(hdu1166)
    记忆化搜索(hdu1078)
    分考场问题。。。
    hdu2087
    cf540C
    x86 寄存器 | DPL,RPL,CPL 之间的联系和区别
    深度学习 | 训练网络trick——mixup
    python | Argparse中action的可选参数store_true,store_false到底是什么意思?
  • 原文地址:https://www.cnblogs.com/qinsungui921112/p/11246812.html
Copyright © 2011-2022 走看看