自学Python之路-Python基础+模块+面向对象
自学Python之路-Python网络编程
自学Python之路-Python并发编程+数据库+前端
自学Python之路-djangohtml
1、初始继承(单继承)前端
继承是指这样一种能力:它可使用现有类的全部功能,并在无需从新编写原来的类的状况下对这些功能进行扩展。python
class A(object):pass # 父类,基类,超类 class B:pass # 父类,基类,超类 class A_son(A,B):pass # 子类,派生类 class AB_son(A):pass # 子类,派生类
没有继承父类,默认继承object 。数据库
抽象即抽取相似或者说比较像的部分。
抽象最主要的做用是划分类别(能够隔离关注点,下降复杂度)。django
继承:是基于抽象的结果,经过编程语言去实现它,确定先经历抽象这个过程,才能经过继承的方式去表达出抽象的结构。编程
抽象只是分析和设计的过程当中,一个动做或者说一种技巧,经过抽象能够获得类。网络
# 好比举例人狗大战。 如下有两个类,你会发现两个类有共同点 class Dog: def __init__(self,name,aggr,hp): self.name = name self.aggr = aggr self.hp = hp def bitc(self,person): person.hp -= self.aggr class person: def __init__(self,name,aggr,hp,sex): self.name = name self.aggr = aggr self.hp = hp self.sex = sex self.money = 0 def attack(self,dog): person.hp -= self.aggr def get_weapon(self,weapon): if self.money >= weapon.price: self.money -= weapon.price self.get_weapon = weapon self.aggr += weapon.aggr else: print("余额不足,请先充值")
将以上两个类相同的地方建立一个新的类, 两个类在继承新的类。并发
class Animal: def __init__(self,name,aggr,hp): self.name = name #人和狗都有本身的昵称 self.aggr = aggr #人和狗都有本身的攻击力 self.hp = hp #人和狗都有本身的生命值 class Dog(Animal): def bitc(self,person): person.hp -= self.aggr class person(Animal): pass Liu = Dog("刘老板",200,500) print(Liu.name)
举个例子:python2.7
一个狗类: 吃、喝、看门编程语言
一个鸟类: 吃、喝、下单
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 __init__(self,name): self.name = name def lay(self): print('laying')
好比定义一个实例 dog = Dog(),其中产生了一个问题
当执行Dog类的时候,Dog类没有__init__(self)就执行父类Animal的__init__(self),而后执行了self.func(),此时Animal和Dog类同时拥有self.func(),那么它执行哪一个类的self.func()? 答案是:Dog的self.func()
提示:
用已经有的类创建一个新的类,这样就重用了已经有的软件中的一部分设置大部分,大大生了编程工做量,这就是常说的软件重用,不只能够重用本身的类,也能够继承别人的,好比标准库,来定制新的数据类型,这样就是大大缩短了软件开发周期,对大型软件开发来讲,意义重大。
固然子类也能够添加本身新的属性或者在本身这里从新定义这些属性(不会影响到父类),须要注意的是,一旦从新定义了本身的属性且与父类重名,那么调用新增的属性时,就以本身为准了。
# 好比接上面的举例。 class Animal: def __init__(self,name,aggr,hp): self.name = name self.aggr = aggr self.hp = hp class Dog(Animal): def __init__(self,name,aggr,hp,kind): self.kind = kind def bitc(self,person): person.hp -= self.aggr Liu = Dog("刘老板",20,500,"吉娃娃") print(Liu.name) # 报错,由于只执行Dog类里面的_init_,可是里面没有name
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) # self.kind = kind # 派生属性(父类没有的,子类新增的属性) class Person(Animal): def __init__(self,name,aggr,hp,sex): Animal.__init__(self,name,aggr,hp) self.sex = sex # 派生属性 self.money = 0 # 派生属性 Liu = Dog('刘老板',20,500,'吉娃娃') Liu.eat() #使用的继承父类animal的eat方法 print(Liu.hp) tong = Person('tong',1,2,None) tong.eat() #使用的继承父类animal的eat方法 print(tong.hp)
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) # self.kind = kind # 派生属性(父类没有的,子类有的属性) def bite(self,person): # 派生方法(父类没有的,子类有的方法) person.hp -= self.aggr 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("余额不足,请先充值") Liu = Dog('刘老板',20,500,'吉娃娃') Liu.eat() #使用的继承父类animal的eat方法 print(Liu.hp) tong = Person('tong',1,2,None) tong.eat() #使用的继承父类animal的eat方法 print(tong.hp) Liu.bite(tong) #使用Dog类本身的派生方法 print(tong.hp)
在子类中,新建的重名的函数属性,在编辑函数内功能的时候,有可能须要重用父类中重名的那个函数功能,应该是用调用普通函数的方式,即:类名.func(),此时就与调用普通函数无异了,所以即使是self参数也要为其传值.
在python3中,子类执行父类的方法也能够直接用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): super().__init__(name,aggr,hp) #等价于Animal.__init__(self,name,aggr,hp),不须要传self self.kind = kind # 派生属性(父类没有的,子类新增的属性) Liu = Dog('刘老板',20,500,'吉娃娃') Liu.eat() #使用的继承父类animal的eat方法 print(Liu.hp)
super()能够在类内使用,也能够在类外使用。
#super()在类外和类内 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): super().__init__(name,aggr,hp) #等价于Animal.__init__(self,name,aggr,hp) self.kind = kind # 派生属性(父类没有的,子类新增的属性) def eat(self):print("dog eating") Liu = Dog('刘老板',20,500,'吉娃娃') print(Liu.name) Liu.eat() # 执行的是Dog类里面的def eat(self):print("dog eating") super(Dog,Liu).eat() # 执行的是父类里面的def eat(self):
class A: def func(self):print("A") class B: def func(self):print("B") class C: def func(self):print("C") class D(A,B,C): # D类继承A,B,C,多继承 def func(self):print("D") d = D() d.func() #此时调用的D类的func()
class A: def func(self):print("A") class B: def func(self):print("B") class C: def func(self):print("C") class D(A,B,C): # D类继承A,B,C,多继承 pass #def func(self):print("D") d = D() d.func() #此时调用的A类的func(),由于class D(A,B,C),A类离D最近
B、C继承A,D继承B、C
class A: def func(self):print("A") class B(A): # B类继承A def func(self):print("B") class C(A): # C类继承A def func(self):print("C") class D(B,C): # D类继承B,C pass #def func(self):print("D") d = D() d.func()
class A: def func(self):print("A") class B(A): # B类继承A pass #def func(self):print("B") class C(A): # C类继承A def func(self):print("C") class D(B,C): # D类继承B,C pass #def func(self):print("D") d = D() d.func()
class A: def func(self):print("A") class B(A): # B类继承A pass #def func(self):print("B") class C(A): # C类继承A pass #def func(self):print("C") class D(B,C): # D类继承B,C pass #def func(self):print("D") d = D() d.func()
同理如下两个问题,继承顺序以下图:
多继承中,咱们子类的对象调用一个方法,默认是就近原则,找的顺序是什么?
① python2.7 新式类和经典类共存,新式类要继承object
② python3 只有新式类,默认继承object
③ 经典类和新式类还有一个区别:mro方法只在新式类中存在,类名.mro方法,查看广度优先的继承顺序。
④ super 只在python3中存在
⑤ super的本质 :不是单纯找父类 而是根据调用者的节点位置的广度优先顺序来的
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()
......