Day 24 继承
# 一、什么是继承
# 继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可成为基类或超类,新建类称为派生类或子类.
# python中类的继承分为:单继承和多继承
class ParentClass1 : #定义父类.
pass
class ParentClass2: #定义父类.
pass
class SubClass1(ParentClass1):#单继承,基类是ParentClass1.
pass
class SubClass2(ParentClass1,ParentClass2):#python 支持多继承,用逗号分开多个继承的类
pass
#查看继承
print(SubClass1.__base__) #只查看从左到右继承的第一个子类,__bases__则是查看继承的所有父类
# <class '__main__.ParentClass1'>
print(SubClass2.__bases__) #查看所有继承的父类
# (<class '__main__.ParentClass1'>, <class '__main__.ParentClass2'>)
# 提示:如果没有指定基类,python的类会默认继承object类,他提供了一些常见方法
print(ParentClass1.__bases__)
#结果(<class 'object'>,)
print(ParentClass2.__bases__)
#结果(<class 'object'>,)
继承与抽象
抽象即抽取类似或者说比较像的部分
抽象分为两个层次
1.将奥巴马和梅西这两个对象比较像的部分抽取成类
2. 将人 ,猪,狗这三个类比较像的部分抽取成父类.
抽象最主要的作用是划分类别(可以隔离关注点,降低复杂度)
继承 :是基于抽象的结果,通过编程语言去实现它,肯定是先经历抽象的这个过程,才能通过继承的方式去表达出抽象的结构.
抽象知识分析和设计的过程中,一个动作或者说一种技巧,通过抽象可以得到类.
二、继承的精讲
# 猫类:吃eat, 喝drink,睡sleep ,爬树 climb
#狗类:吃eat ,喝drink,睡sleep ,看家 watch
# class Pet:
# def __init__(self,name,kind,food):
# self.name =name
# self.kind =kind
# self.food = food
# def eat(self):
# print('%s 吃%s'%(self.name,self.food))
# def drink(self):
# print('%s在喝水'%self.name)
# def sleep(self):
# print('%s在家睡觉'%self.name)
class Cat(Pet):
def climb(self):#派生方法
print('%s在爬树'%self.name)
class Dog(Pet):
def watch(self):#派生方法.
print('%s在看家' %self.name)
tom =Cat('Tom','mao','猫粮') #子类使用名字(方法和静态变量),如果在子类中没有,就使用父类的
#Cat('tom',mao’,'猫粮')实例化
# 实例化这个类
#常见一个空对象
#执行__init__方法:子类没有用父类的
hei=Dog('小黑',"2哈",'狗粮')
tom.eat() #Tom 吃猫粮
hei.eat() #小黑 吃狗粮
hei.watch() #小黑在看家
tom.climb() #Tom在爬树
在开发程序的过程中,如果我们定义了一个类A ,然后取想建立另外一个类B,但是类B的大部分内容与类A的相同时,我们不可能从一开始写一个类B ,这就用到了类的继承的概念。
通过继承的方式新建类B,让B继承A ,B会遗传A的所有属性(数据属性和函数属性),实现代码的重用
三、人狗大战基于继承
class Animal: #动物
def __init__(self,name,aggr,hp):#方法 动态属性 内置的双下方法
self.name=name #对象属性 实例属性
self.aggr =aggr
self.hp =hp
class Person(Animal): #类名 Person
def __init__(self,name,sex,aggr,hp):
self.sex =sex #派生属性
# Animal.__init__(self,name,aggr,hp)
super().__init__(name,aggr,hp)
def attack(self,dog):#自定义方法
print('%s 打了 %s'%(self.name,dog.name))
dog.hp-=self.aggr
class Dog(Animal):
def __init__(self,name,kind,aggr,hp):
self.kind =kind#派生属性
Animal.__init__(self,name,aggr,hp)
super().__init__(name,aggr,hp)
def bite(self,person):
print('%s 咬了%s'%(self.name,person.name))
person.hp -=self.aggr
alex =Person('alex','不详',1,150)
# 首先创建一个person的对象
# 初始化:找init方法,自己有调用自己的.
#父类和子类拥有同名的方法时,子类的对象只会调用子类的
#如果想要调用父类的方法,需要 父类名.方法名(self,其他参数)
hei =Dog('小黑','teddy',260,10000)
alex.attack(hei)
hei.bite(alex)
# 输出结果
# alex 打了 小黑
# 小黑 咬了alex
四、super关键字
#super
class Animal: #动物
def __init__(self,name,aggr,hp):#方法动态属性
self.name =name #实例属性
self.aggr =aggr
self.hp =hp
def eat(self):
print('in Animal eat')
class Person(Animal):#类名Person
def __init__(self,name,sex,aggr,hp):
self.sex = sex
super().__init__(name,aggr,hp)
Animal.__init__(self,name,aggr,hp)
def eat(self):
print('in Person eat')
Animal.eat(self)
super().eat()
alex = Person('alex','不详',1,250)
Animal.eat(alex)
super(Person,alex).eat()
五、多继承问题
class A: def wangwang(self): print('in A') class B(A): def wangwang(self): super().wangwang() # 'in C ' print('in B') class C(A): def wangwang(self): print('in C') class D(B,C):pass d = D() d.wangwang()
答案: D中没有方法去 B 类中查找,其中B类中super().wangwang 按广度优先查找到C类中查找,最终结果为
in C
in B
# python3中的所有类 都默认继承object ,如果一个类 继承了object 这个类就被称为新式类。python3里都为广度优先法则
#经典类 遵循 深度优先算法 且没有mro方法 python2
#新式类 遵循 广度优先算法 有mro方法 py2 py3
# py3 super
# 单继承中 super就是找父类
# 多继承 super寻找的轨迹是根据mro(广度优先)顺序的