• Python学习记录7-继承


    面向对象的三大特性

    • 封装
    • 继承
    • 多态

    封装

    • 封装就是对对象的成员进行访问限制

    • 封装的三个级别:

      • 公开,public
      • 受保护的,protected
      • 私有的,private
      • public,private,protected不是关键字
    • 判断对象的位置

      • 对象内部
      • 对象外部
      • 子类中
    • 私有

      • 私有成员是最高级别的封装,只能在当前类或对象中访问

      • 在成员前面添加两个下划线即可

          class Person():
              # name是公有的成员
              name = "小明"
              # __age是私有的成员
              __age = 18    
        
      • Python的私有不是真私有,是一种称为name mangling的改名策略 可以使用对象,_classname__attributename(_类名__属性名)访问

    • 受保护的封装 protected

      • 受保护的封装是将对象成员进行一定级别的封装,然后,在类中或者子类中都可以进行访问,但是在外部不可以
      • 封装方法:在成员名称前添加一个下划线即可
    • 公开的,公共的 public

      • 公共的封装实际对成员没有人有操作,任何地方都可以访问

    继承

    • 继承就是一个类可以获得另外一个类中的成员属性和成员方法
    • 作用:减少代码,增加代码的复用功能,同时可以设置类与类直接的关系
    • 继承与被继承的概念:
      • 被继承的类叫父类,也叫基类,也叫超类
      • 用于继承的类,叫子类,也叫派生类
      • 继承与被继承一定存在一个 is-a 关系
    
        # 继承的语法
        # 在python中,任何类都有一个共同的父类叫object
        >>> class Person():
                name = 'NoName'
                age = 0
                def sleep(self):
                    print("Sleeping ... ...")
        
        #父类写在括号内
        >>> class Teacher(Person):
                def teach(self):
                    pass
        
        >>> t = Teacher()
        >>> print(t.name)
        >>> print(Teacher.name)
    
        输出:
        NoName
        NoName
        
    
    • 继承的特征

      • 所有的类都继承自object类,即所有的类都是object类的子类
      • 子类一旦继承父类,则子类可以使用父类中除私有成员外的所有内容
      • 子类继承父类后并没有将父类成员完全复制到子类中,而是通过引用关系访问调用
      • 子类中可以定义独有的成员属性和方法
      • 子类中定义的成员和父类成员如果相同,则优先使用子类成员
      • 子类如果想扩充父类的方法,可以在定义新方法的同时访问父类成员来进行代码重用,可以使用 父类名.父类成员 的格式来调用父类成员,也可以使用 super().父类成员的格式来调用
    • 继承变量函数的查找顺序问题

      • 优先查找自己的变量
      • 没有则查找父类
      • 构造函数如果本类中没有定义,则自动查找调用父类构造函数
      • 如果本类有定义,则不再继续向上查找
    • 构造函数

      • 是一类特殊的函数,在类进行实例化之前进行调用
      • 如果定义了构造函数,则实例化时使用构造函数,不查找父类构造函数
      • 如果没定义,则自动查找父类构造函数
      • 如果子类没定义,父类的构造函数带参数,则构造对象时的参数应该按父类参数构造
    • super

      • super不是一个关键字,而是一个类
      • super的作用是获取MRO(MethodResolustionOrder)列表中的第一个类
      • super于父类直接没有任何实质性关系,但通过super可以调用到父类
      • super使用两个方法,参见在构造函数中调用父类的构造函数
    
        >>> class Person(object):
                name = 'NoName'
                age = 18
                __score = 0 # 考试成绩是秘密,只要自己知道 
                _petname = "sec" #小名,是保护的,子类可以用,但不能公用
                def sleep(self):
                    print("Sleeping ... ...")
    
    
        >>> class Teacher(Person):
                pass 
    
        # 创建一个Teacher类实例    
        >>> t = Teacher()
        # 子类实例访问父类public类型的变量  可以
        >>> print(t.name)
        # 子类实例访问父类的protected类型的变量   可以
        >>> print(t._petname)
        # 子类访问父类的private类型的变量   不可以 
        # print(t.__score)
    
        >>> p = Person()
        >>> print(p._Person__score)
    
        >>> print('*' * 20)
        >>> print(id(Person.name))
        >>> print(id(t.name))
    
        >>> t.sleep()
        
        输出:
        NoName
        sec
        0
        ********************
        4496482928
        4496482928
        Sleeping ... ...
    
    
    
        # 子类和父类定义同一个名称变量,则优先使用子类本身
        >>> class Person(object):
                name = 'NoName'
                age = 18
                __score = 0 # 考试成绩是秘密,只要自己知道 
                _petname = "sec" #小名,是保护的,子类可以用,但不能公用
                def sleep(self):
                    print("Sleeping ... ...")
    
    
        >>> class Teacher(Person):
                name = '我是老师的名字'   
    
    
        >>> t = Teacher()
        >>> print(t.name)
    
        输出:
        我是老师的名字
    
    
    
        # 子类扩充父类功能
        # 人有工作的函数 老是也有工作的函数 ,但老师的工作是讲课
        >>> class Person(object):
                name = 'NoName'
                age = 18
                __score = 0 # 考试成绩是秘密,只要自己知道 
                _petname = "sec" #小名,是保护的,子类可以用,但不能公用
                def sleep(self):
                    print("Sleeping ... ...")
                def work(self):
                    print("make some money...")
    
    
        >>> class Teacher(Person):
                name = '我是老师的名字' 
                def make_test(self):
                    print("attention")
                def work(self):
                    # 扩充父类的功能只需要调用父类相应的函数
                    #Person.work(self)
                    # 扩充父类的另一种方法
                    # super代表得到父类
                    super().work()
                    self.make_test()
    
        >>> t = Teacher()
        >>> t.work()
    
        输出:
        make some money...
        attention
    
    
        
        # 构造函数的概念
    
        >>> class Dog():
                # __init__就是构造函数
                # 每次实例化的时候,第一个被自动的调用
                # 主要工作是进行初始化
                def __init__(self):
                    print("I am init in dog")
    
        >>> kaka = Dog() # 实例化的时候自动调用了构造函数,括号内参数需要跟构造函数的参数匹配
    
        输出:
        I am init in dog
    
    
        
        # 继承中的构造函数  -1
        >>> class Animal():  # 动物
                pass
    
        >>> class mammal(Animal):  #哺乳动物
                pass
    
        >>> class Dog(mammal):  # 狗是哺乳动物
                # __init__就是构造函数
                # 每次实例化的时候,第一个被自动的调用
                # 主要工作是进行初始化
                def __init__(self):
                    print("I am init in dog")
    
        # 实例化的时候 自动调用了Dog的构造函数        
        >>> kaka = Dog()  
        
        输出:
        I am init in dog
    
    
        
        # 继承中的构造函数  -2
        >>> class Animal():  # 动物
                pass
    
        >>> class mammal(Animal):  #哺乳动物
                def __init__(self):
                    print("我是哺乳动物的父类")
    
        >>> class Dog(mammal):  # 狗是哺乳动物
                # __init__就是构造函数
                # 每次实例化的时候,第一个被自动的调用
                # 主要工作是进行初始化
                def __init__(self):
                    print("I am init in dog")
    
        # 实例化的时候 自动调用了Dog的构造函数        
        >>> kaka = Dog()   
    
    
        # 猫没有用写构造函数
        >>> class Cat(mammal):
                pass
    
        # 此时应该自动调用构造函数,因为Cat没有构造函数,所以查找父类的构造函数
        # 在父类mammal中查找到了构造函数,则停止向上查找
        >>> c = Cat()
    
        输出:
        I am init in dog
        我是哺乳动物的父类
    
    
    
        # 继承中的构造函数  -3
        >>> class Animal():  # 动物
                pass
    
        >>> class mammal(Animal):  #哺乳动物
                def __init__(self, name):
                    print("我是哺乳动物的父类{0}".format(name))
    
        >>> class Dog(mammal):  # 狗是哺乳动物
                # __init__就是构造函数
                # 每次实例化的时候,第一个被自动的调用
                # 主要工作是进行初始化
                def __init__(self):
                    print("I am init in dog")
    
        # 实例化Dog时,查找到Dog的构造函数,参数匹配,不报错      
        >>> kaka = Dog()
    
        >>> class Cat(mammal):
                pass
    
        # 实例化Cat类时,调用Cat类的构造函数,由于Cat没有构造函数,则向上查找,查找到父类mammal的构造,停止查找
        # 因为mammal的构造函数需要两个参数,实例化的时候给了一个,报错
        >>> #c = Cat()
    
        输出:
        I am init in dog
    
    
    
    
        # 继承中的构造函数  -4
        >>> class Animal():  # 动物
                 def __init__(self):
                    print("我是动物")
    
        >>> class mammal(Animal):  #哺乳动物
                pass
    
        >>> class Dog(mammal):  # 狗是哺乳动物
                pass
    
        # 实例化Dog类时候,没有构造函数 一直向上查找,直到Animal类    
        >>> kaka = Dog() 
    
        输出:
        我是动物
    
    
  • 相关阅读:
    九、顺序表和单链表的对比分析
    八、单链表的实现
    七、线性表的链式存储结构
    【小白成长撸】--顺序栈(C语言版)
    【小白成长撸】--反向链表(一)
    【小白成长撸】--链表创建
    股票数据获取(参考用)
    VBA运用3_股票_Module2
    VBA运用3_股票_Module1
    股市交易时间
  • 原文地址:https://www.cnblogs.com/yanht/p/11695127.html
Copyright © 2020-2023  润新知