继承

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

 

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

# 狗类 吃 喝 看门
# 鸟类 吃 喝 下蛋

class Animal:
    def __init__(self):
        print("执行Animal.__init__")
        self.func()

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

    def drink(self):
        print("%s drinking" % self.name)

    def func(self):
        print("Animal.func")


class Dog(Animal):
    def guard(self):
        print("guarding")

    def func(self):
        print("Dog.func")


class Bird(Animal):
    def lay_egg(self):
        print("鸟会下蛋")


dog = Dog()

查看继承

>>> SubClass1.__bases__ #__base__只查看从左到右继承的第一个子类,__bases__则是查看所有继承的父类
(<class '__main__.ParentClass1'>,)
>>> SubClass2.__bases__
(<class '__main__.ParentClass1'>, <class '__main__.ParentClass2'>)

 

super

class A:
    def hahaha(self):
        print('A')

class B(A):
    def hahaha(self):
        super().hahaha()
        #super(B,self).hahaha()
        #A.hahaha(self)
        print('B')

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

 

派生

class Animal:
    def __init__(self, name, aggr, hp):
        self.name = name
        self.aggr = aggr
        self.hp = hp

    def eat(self):
        print('吃药回血')
        self.hp += 100


class Dog(Animal):
    def __init__(self, name, aggr, hp, kind):
        Animal.__init__(self, name, aggr, hp)  # super().__init__(name, aggr, hp)  # 执行父类Animal的init方法
        self.kind = kind  # 派生属性

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

    def bite(self, person):  # 派生方法
        person.hp -= self.aggr


jin = Dog('金老板', 100, 500, '吉娃娃')
jin.eat()
print(jin.hp)


class Person(Animal):
    def __init__(self, name, aggr, hp, sex):
        Animal.__init__(self, name, aggr, hp)
        self.sex = sex  # 派生属性
        self.money = 0  # 派生属性

    def attack(self, dog):
        dog.hp -= self.aggr

    def get_weapon(self, weapon):
        if self.money >= weapon.price:
            self.money -= weapon.price
            self.weapon = weapon
            self.aggr += weapon.aggr
        else:
            print("余额不足,请先充值")


alex = Person('alex', 1, 2, None)
alex.eat()
print(alex.hp)

jin.bite(alex)
print(alex.hp)

# 父类中没有的属性 在子类中出现 叫做派生属性
# 父类中没有的方法 在子类中出现 叫做派生方法
# 只要是子类的对象调用,子类中有的名字 一定用子类的,子类中没有才找父类的,如果父类也没有报错
# 如果父类 子类都有 用子类的
# 如果还想用父类的,单独调用父类的:
#       父类名.方法名 需要自己传self参数
#       super().方法名 不需要自己传self

 

多继承

# coding:utf-8
# class F:
#     def func(self): print('F')
# class A(F):pass
#     # def func(self): print('A')
# class B(A):
#     pass
#     # def func(self): print('B')
# class E(F):pass
#     # def func(self): print('E')
# class C(E):
#     pass
#     # def func(self): print('C')
#
# class D(B,C):
#     pass
#     # def func(self):print('D')
#
# d = D()
# # d.func()
# print(D.mro())

# 新式类中的继承顺序 : 广度优先


class A(object):
    def func(self): print('A')

class B(A):
    def func(self):
        super().func()
        print('B')

class C(A):
    def func(self):
        super().func()
        print('C')

class D(B,C):
    def func(self):
        super().func()
        print('D')

b = D()
b.func()
print(B.mro())
#2.7
# 新式类 继承object类的才是新式类 广度优先
# 经典类 如果你直接创建一个类在2.7中就是经典类 深度优先
# print(D.mro())
# D.mro()

# 单继承 : 子类有的用子类 子类没有用父类
# 多继承中,我们子类的对象调用一个方法,默认是就近原则,找的顺序是什么?
# 经典类中 深度优先
# 新式类中 广度优先
# python2.7 新式类和经典类共存,新式类要继承object
# python3   只有新式类,默认继承object
# 经典类和新式类还有一个区别  mro方法只在新式类中存在
# super 只在python3中存在
# super的本质 :不是单纯找父类 而是根据调用者的节点位置的广度优先顺序来的

# 继续写作业 :
# 学生管理系统  登录,识别身份   进阶 : 不同视图不同的菜单