022_继承_派生_多继承_砖石继承

时间:2019-03-19
本文章向大家介绍022_继承_派生_多继承_砖石继承,主要包括022_继承_派生_多继承_砖石继承使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

1,什么是继承

继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类

2,python中类的继承分为:单继承和多继承

  2.1,定义类时,类名后面的括号是用来表明关系的,不是用来传参的。

class ParentClass1: #定义父类
    pass

class ParentClass2: #定义父类
    pass

class SubClass1(ParentClass1): #单继承,基类是ParentClass1,派生类是SubClass
    pass

class SubClass2(ParentClass1,ParentClass2): #python支持多继承,用逗号分隔开多个继承的类
    pass

  2.2,查看继承

>>> SubClass1.__bases__ #__base__只查看从左到右继承的第一个子类,__bases__则是查看所有继承的父类
(<class '__main__.ParentClass1'>,)
>>> SubClass2.__bases__
(<class '__main__.ParentClass1'>, <class '__main__.ParentClass2'>)
>>>ParentClass1.__bases__
(<class 'object'>,)	#任何一个没有父类的类都是object的子类。python3中没有继承的默认继承object类。

3,在定义类时,在默认执行__init__(self)之前,就会默认建立了一个空白对象self。

  在当面的代码中,创建dog对象时,通过Dog类创建,此时已经创建了Dog的空白对象self,在默认执行__init__(self)时,自己并没有,就会执行父类里的,因此,传给父类的__init__(self)方法的对象是Dog的空白对象self。所以,执行里面的self.func()时,应该是Dog的func()
 
 class Animal:
    def __init__(self):
        print('执行Animal.__init__')
        self.func()

class Dog(Animal):
    def func(self):
        print('Dog.func')

dog = Dog()

4,继承

  在开发程序的过程中,如果我们定义了一个类A,然后又想新建立另外一个类B,但是类B的大部分内容与类A的相同时
  我们不可能从头开始写一个类B,这就用到了类的继承的概念。
  通过继承的方式新建类B,让B继承A,B会‘遗传’A的所有属性(数据属性和函数属性),实现代码重用

 
class Animal:
    '''
    人和狗都是动物,所以创造一个Animal基类
    '''
    def __init__(self, name, aggressivity, life_value):
        self.name = name  # 人和狗都有自己的昵称;
        self.aggressivity = aggressivity  # 人和狗都有自己的攻击力;
        self.life_value = life_value  # 人和狗都有自己的生命值;

    def eat(self):
        print('%s is eating'%self.name)

class Dog(Animal):
    pass

class Person(Animal):
    pass

egg = Person('egon',10,1000)
ha2 = Dog('二愣子',50,1000)
egg.eat()
ha2.eat()

5,supper

  在子类中,新建的重名的函数属性,在编辑函数内功能的时候,有可能需要重用父类中重名的那个函数功能,应该是用调用普通函数的方式,即:类名.func(),此时就与调用普通函数无异了,因此即便是self参数也要为其传值.
  在python3中,子类执行父类的方法也可以直接用super方法 
class A:
    def hahaha(self):
        print('A')

class B(A):
    def hahaha(self):
        super().hahaha() #“supper(类名,对象名).方法名” #super(B,self).hahaha(),在本类中参数可以不写,默认传本类的类名和对象。 此方法也可用于类外。
        #A.hahaha(self)
        print('B')

a = A()
b = B()
b.hahaha()
super(B,b).hahaha()

6,派生

class Animal:
    '''
    人和狗都是动物,所以创造一个Animal基类
    '''
    def __init__(self, name, aggressivity, life_value):
        self.name = name  # 人和狗都有自己的昵称;
        self.aggressivity = aggressivity  # 人和狗都有自己的攻击力;
        self.life_value = life_value  # 人和狗都有自己的生命值;

    def eat(self):
        print('%s is eating'%self.name)

class Dog(Animal):
    '''
    狗类,继承Animal类
    '''
    def __init__(self,name,breed,aggressivity,life_value):
        super().__init__(name, aggressivity, life_value) #执行父类Animal的init方法
        self.breed = breed  #派生出了新的属性

    def bite(self, people):
        '''
        派生出了新的技能:狗有咬人的技能
        :param people:  
        '''
        people.life_value -= self.aggressivity

    def eat(self):
        # Animal.eat(self)
        #super().eat()
        print('from Dog')

class Person(Animal):
    '''
    人类,继承Animal
    '''
    def __init__(self,name,aggressivity, life_value,money):
        #Animal.__init__(self, name, aggressivity, life_value)
        #super(Person, self).__init__(name, aggressivity, life_value)
        super().__init__(name,aggressivity, life_value)  #执行父类的init方法
        self.money = money   #派生出了新的属性

    def attack(self, dog):
        '''
        派生出了新的技能:人有攻击的技能
        :param dog: 
        '''
        dog.life_value -= self.aggressivity

    def eat(self):
        #super().eat()
        Animal.eat(self)    #如果既想实现新的功能也想使用父类原本的功能,还需要在子类中再调用父类
        print('from Person')

egg = Person('egon',10,1000,600)
ha2 = Dog('二愣子','哈士奇',10,1000)
print(egg.name)
print(ha2.name)
egg.eat()

7,继承顺序

8,多继承中的砖石继承

 # 父类中没有的属性 在子类中出现 叫做派生属性
# 父类中没有的方法 在子类中出现 叫做派生方法
# 只要是子类的对象调用,子类中有的名字 一定用子类的,子类中没有才找父类的,如果父类也没有报错
# 如果父类 子类都有 用子类的
    # 如果还想用父类的,单独调用父类的:
    #       父类名.方法名 需要自己传self参数
    #       super().方法名 不需要自己传self
# 正常的代码中 单继承 === 减少了代码的重复
# 继承表达的是一种 子类是父类的关系