面向对象-类的继承

类的继承

1、概述

面向对象编程最大的好处就是实现了代码的重用 代码的重用是通过继承来去实现的 继承就分为父类和子类 被继承的类称为父类、超类、基类,继承后新的类称为子类

2、单一继承

  • 格式

    class 父类:
    	pass
    class 子类(父类):
    	pass
    
  • 好处

    继承最大的好处(代码的重用) 子类什么事都没做 就拥有了父类的所有属性和方法

  • 注意

    私有不能被继承

  • 实例

    所有公有属性和方法的继承

    class A(object):
        money = 1000
    
        def say(self):
            print('我老有钱了', self.money)
    
    
    # 子类B什么都没做  就拥有了父类的所有公有属性和方法
    class B(A):
        pass
    
    a = A()
    print(a.money)
    a.say()
    b = B()
    print(b.money)
    b.say()
    

    私有属性和方法的继承(私有都不能被继承(私有属性/私有方法))

    class A:
        name = 'A'
        __age = 18
    
        def say(self):
            print('我叫:{} 我今年{}岁了'.format(self.name, self.__age))
            # 公有方法调用私有方法
            self.__private_method()
    
        def __private_method(self):
            print('我就是一个私有方法')
    
    
    class B(A):
        def test_private(self):
            # print(self.__age)
            self.__private_method()
            
    a = A()
    print(a.name)
    a.say()
    b = B()
    print(b.name)
    b.say()
    b = B()
    b.test_private()
    # 私有都不能被继承(私有属性/私有方法)
    

    父类方法的重写(不影响父类)

    class A:
        name = ''
        def __init__(self, name):
            self.name = name
        def say(self):
            # self依然是谁调用就是谁
            print('A', self.__class__)
            print('我叫:',self.name)
    
    class B(A):
        # 对于父类方法的重写啊(覆盖掉了)
        def say(self):
            print('我是子类的say', self.name)
    
    a = A('张三')
    a.say()
    b = B('张三')
    b.say()
    

    完整实例

    class People:
        # 定义基本属性
        name = ''
        age = 0
        # 定义私有属性
        __weight = 0
    
        # 定义构造方法
        def __init__(self, n, a, w):
            self.name = n
            self.age = a
            self.__weight = w
    
        def speak(self):
            print("{} 说我今年{}岁了 ".format(self.name, self.age))
    
    # p = People('lucky', 18, 99)
    # p.speak()
    class Stu(People):
        # 基本属性
        grade = ''
        def __init__(self, n, a, w, g):
            People.__init__(self, n, a, w)
            self.grade = g
    
        def speak(self):
            print('{}说 我今年{}岁了 我在读{}'.format(self.name, self.age, self.grade))
    
    # s = Stu('lucky', 18, 99)
    s = Stu('lucky', 18, 99, '小学五年级')
    s.speak()
    

3、多继承

  • 格式

    class 子类(父类1[,父类2...]):
    	pass
    
  • 注意

    需要注意继承父类的顺序 若是基类中有相同的方法名的时候 而在子类中未指定 会在父类中按照从左至右的顺序进行搜索 即在子类中不存在该方法 则去父类从左至右进行查找 直至查到为止

  • 实例

    class A:
        def a(self):
            print('A类中的a方法')
    
    class B:
        val = '值'
        def b(self):
            print('B类中的b方法', self.val)
    
    class C(A, B):
        pass
    
    c = C()
    # print(c.val)
    # c.a()
    c.b()
    

    将之前的people、stu变成多继承

    class People:
        # 定义基本属性
        name = ''
        age = 0
        # 定义私有属性
        __weight = 0
    
        # 定义构造方法
        def __init__(self, n, a, w):
            self.name = n
            self.age = a
            self.__weight = w
    
        def speak(self):
            print("{} 说我今年{}岁了 ".format(self.name, self.age))
    
    class Stu(People):
        # 基本属性
        grade = ''
        def __init__(self, n, a, w, g):
            People.__init__(self, n, a, w)
            self.grade = g
    
        def speak(self):
            print('{}说 我今年{}岁了 我在读{}'.format(self.name, self.age, self.grade))
    
    class Speaker:
        # 给speaker类定义基本属性
        topic = ''
        name = ''
    
        def __init__(self, n, t):
            self.topic = t
            self.name = n
    
        def speak(self):
            print('我叫:{} 我是一个演说家 我演讲的话题是:{}'.format(self.name, self.topic))
    
    # 多重继承
    class Sample(Speaker, Stu):
        val = ''  # 定义sample基本属性
    
        def __init__(self, n, a, w, g, t, val):
            Speaker.__init__(self, n, t)
            Stu.__init__(self, n, a, w, g)
            self.val = val
    
    
    # s = Sample('lucky', '学习python')
    # s = Sample('lucky', 18, 99, 'python36')
    s = Sample('lucky', 18, 99, 'python36', '学习python', 'default')
    s.speak()
    

4、调用父类方法

  • 方式

    • 方式一

      super(类名, self).method()

    • 方式二(建议)

      super().method()

    • 方式三

      类名.method(self)

  • 注意

    • 如果是单继承 则super自动调用父类被覆盖的方法
    • 如果是多继承 super会从最左侧的类开始查找 遇到则调用
    • 使用super(类名, self) 调用方式 会根据你给的类名 往右开始进行查找 查找成功则调用 查找失败 则抛出异常
    • 建议使用super() 调用方式 因为如果使用类名.方法名的方式 一旦类名发生更改 后期维护困难
  • 使用

    单继承

    class A:
        name = ''
        def __init__(self, n):
            self.name = n
    
        def say(self):
            print('A类的say方法')
    
    class B(A):
        age = ''
        def __init__(self, n, a):
            # 第一种 通过类名调用
            # A.__init__(self, n)
            # super 方法调用
            super().__init__(n)
            self.age = a
        # 对于父类say方法的重写
        def say(self):
            print('子类的say方法')
            
        def say1(self):
            # 第一种调用父类say方法
            A.say(self)
    
        def say2(self):
            # 第二种调用父类say方法
            super().say()
    
    b = B('lucky', 18)
    # print(b.age)
    # print(b.name)
    b.say()
    

    多继承

    class A:
        def say(self):
            print('A类的say方法')
    
    class B:
        def say(self):
            print('B类的say方法')
    
    
    class C(A, B):
        def say(self):
            # print('C类的say方法')
            # 第一种 类名调用父类方法
            # B.say(self)
            # 使用super() 无参调用父类方法
            # super().say()  # 默认从左往右查 遇到就调用
            # 使用super() 带参调用父类方法
            # super(C, self).say()  ==  super().say()
            super(A, self).say()  # 从A类开始往右查找
            # super(B, self).say()  # AttributeError: 'super' object has no attribute 'say'
    
    
    c = C()
    c.say()
    
posted @ 2022-03-18 14:16  寻月隐君  阅读(71)  评论(0编辑  收藏  举报