Python Class 类的继承与多继承

本文介绍了Python中的类继承概念,包括继承的访问控制、示例、多继承及其解决冲突的算法、类装饰器的使用、类抽象方法以及函数和类方法名称的注意事项。通过多个示例详细阐述了如何在Python中实现和使用继承,特别是多继承的应用和潜在问题。
摘要由CSDN通过智能技术生成

1、继承概念

  • 面向对象的三要素之一:继承 inheritance

  • 在面向对象的世界中,从父类继承,就可以直接拥有父类的属性和方法,这样可以减少代码、多复用。子类可以定义自己的属性和方法

  • 继承: class 子类(父类) 这种形式就是从父类继承,括号中写上继承的类的列表。继承可以让子类从父类获取特征(属性和方法)

  • 父类:也称为 基类 超类

  • 子类:也称为 派生类

  • 定义:

    class 子类名(基类1[, 基类2, ...]):
        语句块
    
  • 如果定义时,没有基类列表,等同于继承object

  • 在Python3中, object类是所有对象的根基类

  • Python支持多继承,继承也可以多级

  • 查看继承的特殊属性和方法有:
    在这里插入图片描述

2、继承中的访问控制

  • 从父类继承,自己没有的,就可以到父类中找
  • 私有的都是不可以访问的,但是本质上依然是改了名称放在这个属性所在类或实例的__dict__中,知道这个新名称就可以直接找到这个隐藏的变量,这是个黑魔法技巧,慎用
  • 继承时,共有的,子类和实例都可以随意访问;私有成员被隐藏,子类和实例不可直接访问,但私有变量所在的类内的方法中可以访问这个私有变量
  • 私有属性最好只在当前类中使用,修改名称时,在哪个类里修改为哪个类的名称
  • 实例属性查找顺序:实例的__dict__ ===> 类__dict__ === 如果有继承 ===> 父类__dict
  • 继承关系中,同一种方法,在不同的类中有不同的表现方法,这就叫Python的多态
  • 自己的私有属性,就该自己的方法读取和修改,不要借助其他类的方法,即使是父类或者派生类的方法
  • 作为好的习惯,如果父类定义了__init__方法,就该在子类的__init__中调用它

3、示例

3.1 示例 1

class Animal:
    def __init__(self, name):
        self._name = name
        
    def shout(self):
        print('{} shouts.'.format(self.__class__.__name__))
        
    @property
    def name(self):
        return self._name
    
a = Animal('Monster')
a.shout()  # Animal shouts.
a.name  # 'Monster'

class Dog(Animal):
    pass

dog = Dog('Maltese')
dog.shout()  # Dog shouts.
dog.name  # 'Maltese'

class Cat(Animal):
    pass

cat = Cat('Garfield')
cat.shout()  # Cat shouts.
cat.name  # 'Garfield'
Cat.__base__  # __main__.Animal   
Cat.__bases__  # (__main__.Animal,)
Cat.__mro__  # (__main__.Cat, __main__.Animal, object)
Cat.mro()  # [__main__.Cat, __main__.Animal, object]
Animal.__subclasses__()  # [__main__.Dog, __main__.Cat]

3.2 示例 2

看懂如下示例,继承就可以完全get了。

class Animal:
    __COUNT = 100  # _Animal__COUNT
    HEIGHT = 0
    
    def __init__(self, age, weight, height):
        self.__COUNT += 1  # slef._Animal__COUNT
        self.age = age
        self.__weight = weight  # self._Animal__COUNT
        self.HEIGHT = height
    
    def eat(self):
        print("{} eat".format(self.__class__.__name__))
        
    def __getweight(self):
        print(self.__weight)  # self._Animal__COUNT
        
    @classmethod
    def showcount1(cls):
        print(cls)
        print(cls.__dict__)
        print(cls.__COUNT)  # cls._Animal__COUNT
    
    @classmethod
    def __showcount2(cls):
        print(cls.__COUNT)  # cls._Animal__COUNT
        
    def showcount3(self):
        print(self.__COUNT)  # self._Animal__COUNT
        

class Cat(Animal):
    NAME = 'CAT'
    __COUNT = 200

c = Cat(3, 5, 15)
print(c.__dict__)  # {'_Animal__COUNT': 101, 'age': 3, '_Animal__weight': 5, 'HEIGHT': 15}
print(c.HEIGHT)  # 15
# print(c.__COUNT)  # 'Cat' object has no attribute '__COUNT'
# c.__getweight()  #  'Cat' object has no attribute '__getweight'
c._Animal__getweight()  # 5  【注意,隐藏属性改名的只和当前类有关系,设置私有属性的当前类,在谁里面改谁的名】
c.showcount1()  # 自己没有的,会和父类去要
    # <class '__main__.Cat'>
    # {'__module__': '__main__', 'NAME': 'CAT', '_Cat__COUNT': 200, '__doc__': None}
    # 100 

# c.__showcount2()  # 'Cat' object has no attribute '__showcount2'
c._Animal__showcount2()  # 100
c.showcount3()  # 101
print(Cat.__dict__)  # {'__module__': '__main__', 'NAME': 'CAT', '_Cat__COUNT': 200, '__doc__': None}
print(c._Cat__COUNT)  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值