python--面向对象:继承
继承是创建新类的方式,新建的类可以继承多个父类(python里),父类又称为基类和超类,新建的类又称为派生类和子类
如果没有基类,python默认继承object祖类,object是所有类的基类
一、继承分为单继承和多继承
class Animal:pass #父类 超类 可以有Cat Dog两个子类
class Cat(Animal):pass # 单继承:只继承一个父类,
class Dog(Cat,Animal):pass # 多继承:可以继承多个父类
二、查看继承
class Animal:
def d(self):pass
class Cat(Animal):
def func(self):pass
class Dog(Cat,Animal):pass
print(Dog.__base__) #<class '__main__.Cat'> 查看子类从左到右继承的第一个父类
print(Dog.__bases__) #(<class '__main__.Cat'>, <class '__main__.Animal'>) 查看子类所有的父类
三、继承与抽象(先抽象再继承)
抽象是抽取类似或者比较像的部分:比如周杰伦,蔡依林抽象为人, 金毛,泰迪抽象为狗 最后人和狗都抽象为动物,通过抽象得到类
继承是基于抽象的结果,通过继承的方式去表达出抽象的
那么问题来了什么时候会用到继承呢?有这样一段代码
class Cat:
def __init__(self,name,sex,color,eat):
self.c_name=name
self.c_sex=sex
self.c_color=color
self.c_eat=eat
def beauty_cat(self):
return '%s喜欢吃%s'%(self.c_name,self.c_eat)
class Dog:
def __init__(self,name,sex,color,eat,age):
self.c_name = name
self.c_sex = sex
self.c_color = color
self.c_eat = eat
self.c_age = age
def duty_dog(self):
return '%s是%s毛色'%(self.c_name,self.c_color)
mimi=Cat('mimi','女','white','fish')
tide=Dog('tide','男','dark','meat',2)
print(mimi.beauty_cat())
print(tide.duty_dog())
这时候我们发现猫和狗的属性惊人的相似,这么冗余的代码我们怎么能忍受!这时候我们想到了继承,首先抽象出一个父类Animal
然后让cat dog 继承Animal 解题如下:
class Animal: # 定义父类,抽象出一致的属性:name,sex,color,eat
def __init__(self, name, sex, color, eat):
self.c_name = name
self.c_sex = sex
self.c_color = color
self.c_eat = eat class Cat(Animal):
def beauty_cat(self): # 猫的属性和父类Animal完全一致,就可以不用写属性,自己没有的会自动找父类调用
return '%s喜欢吃%s' % (self.c_name, self.c_eat) class Dog(Animal):
def __init__(self, name, sex, color, eat, age): # Dog有自己独有的属性age,所有需要init再定义一个自己独有的属性age,
Animal.__init__(self, name, sex, color, eat) # 并且要把共有的 name, sex, color, eat属性都传进去,但是自己没有定义这些共有属性,需要调用父类的init
super().__init__(name, sex, color, eat) #super()实现的功能和Animal.__init__(self, name, sex, color, eat)一样,可以不用再传self,而且会自动找父类
self.age = age # 派生属性 # 所以在这里需要调用Animal.__init__(),并把父类的参数一并传进去 def duty_dog(self): # 派生方法
return '%s是%s毛色' % (self.c_name, self.c_color) mimi = Cat('mimi', '女', 'white', 'fish')
tide = Dog('tide', '男', 'dark', 'meat', 2)
print(mimi.beauty_cat())
print(tide.duty_dog())
小结:
# 继承:
"""
继承的作用:减少代码的重用
提高代码可读性
规范编程模式
1.可以提高代码的复用性
2.一个类 可以被多个类继承
3.一个类 可以继承多个父类 —— python里
""" # 派生:
"""
1.子类也可以自己新增一些自己独特属性,但是如果名字和父类的是名字重复,那么调用新增属性的时候,会先以自己定义的为准
2.父类中没有的属性 在子类中出现 叫做派生属性
3.父类中没有的方法 在子类中出现 叫做派生方法
"""
# 调用:
"""
1.子类对象的调用,如果子类有的先用自己的,自己没有的再找父类的,父类没有就报错
2.父类名.方法名()调用父类中的init,但是需要自己传self
3.super() 不用自己传self,功能同上
"""
# 注释:
"""
1.正常的代码中 用单继承 === 减少了代码的重复
2.继承表达的是一种 子类是父类的关系 记住是————'是'————的关系,以后看到谁是谁的,就要想到可不可以用继承,eg教授是老师
3.之前的组合是表示————'有'————的关系 eg:老师有生日, """
继承进阶练习:人狗大战,人加武器
class Dog:
def __init__(self, name, aggr, hp, kind):
self.name = name
self.aggr = aggr
self.hp = hp
self.kind = kind def bite(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):
dog.hp -= self.aggr def get_weapon(self, weapon):
if self.money >= weapon.w_price:
self.money -= weapon.w_price
self.weapon = weapon
self.aggr=weapon.w_aggr
else:
print('余额不足,请充值') class Weapon:
def __init__(self, name, aggr, njd, price):
self.w_name = name
self.w_aggr = aggr
self.w_njd = njd
self.w_price = price def hand_w(self, dog):
if self.w_njd > 0:
dog.hp -= self.w_aggr*2
self.w_njd -= 1
tide = Dog('tide',100,200,'咬人')
join = Person('join',50,10,'打狗')
shoot = Weapon('shoot', 20, 3, 500)
join.money += 1000
join.get_weapon(shoot)
join.attack(tide)
print(join.hp) #
print(tide.hp) #
shoot.hand_w(tide)
print(join.hp)
print(tide.hp)
原版
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):
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.w_price:
self.money -= weapon.w_price
self.weapon = weapon
self.aggr=weapon.w_aggr
else:
print('余额不足,请充值') class Weapon:
def __init__(self, name, aggr, njd, price):
self.w_name = name
self.w_aggr = aggr
self.w_njd = njd
self.w_price = price def hand_w(self, dog):
if self.w_njd > 0:
dog.hp -= self.w_aggr*2
self.w_njd -= 1
tide = Dog('tide',100,200,'咬人')
join = Person('join',50,10,'打狗')
shoot = Weapon('shoot', 20, 3, 500)
join.money += 1000
join.get_weapon(shoot)
join.attack(tide)
print(join.hp) #
print(tide.hp) #
shoot.hand_w(tide)
print(join.hp)
print(tide.hp)
继承版
四、新式类中的继承顺序
广度优先,尽量不错过所有继承的类,由于BC都继承了A类,所以在注释了B 类之后,系统会感知到
C类也继承了A,最终从C类,也会找到A类,为了不遗漏C,所以从广度来说在注释了B 类之后,会先执行C类的程序。
新式类 继承object类的才是新式类 广度优先
class A:
def func(self):
return '你好'
class B(A):pass
def func(self):
return '我好'
class C(A):pass
def func(self):
return '大家好'
class D(B,C):pass
def func(self):
return '人人好'
先实例化一个join 调用jion.func
#第一种 情况,自己有func,先执行自己的 打印出‘人人好’
join=D()
print(join.func()) #人人好
#第二种情况,注释掉D类中的func,写上pass,会根据广度优先找到最近继承的B类,打印B类中的‘我好’
print(join.func()) #我好
#第三种情况,注释掉B类中的func,写上pass,会根据广度优先找到最近继承的C类,打印C类中的‘大家好’
print(join.func()) #大家好
# 第四种情况,注释掉C类中的func,写上pass,会根据广度优先找到最近继承的A类,打印A类中的'你好'
print(join.func()) #'你好'
砖石继承顺序
class A:
def func(self):
return '你好'
class B():pass
def func(self):
return '我好'
class C(B):pass
def func(self):
return '大家好'
class D(A):pass
def func(self):
return '人人好'
class E(C,D):pass
def func(self):
return '不好'
先实例化一个join 调用jion.func
#第一种 情况,自己有func,先执行自己的
join=E()
print(join.func()) #不好
#第二种情况,注释掉E类中的func,写上pass,会根据广度优先找到最近继承的C类,
print(join.func()) #大家好
#第三种情况,注释掉C类中的func,写上pass,会根据广度优先找到最近继承的B类,打印B类中的‘我好’
print(join.func()) #我好
#第四种情况,注释掉B类中的func,写上pass,会根据广度优先找到最近继承的D类,打印A类中的'人人好'
print(join.func()) #人人好
#第五种情况,注释掉D类中的func,写上pass,会根据广度优先找到最近继承的A类,打印A类中的'你好'
print(join.func()) #你好
进阶继承
ass 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() #打印顺序是A C B D
pr
查看继承的顺序 mro 还有super
五、经典类 如果你直接创建一个类在2.7中就是经典类 深度优先
六、小结
#小结:
'''
单继承 子类有的就用自己的,没有就用父类的
多继承 就近原则,顺序是:新式类广度优先;经典类深度优先
py2中 新式类和经典类共存,但是新式类要继承object
py3中只有新式类
mro 查看继承的顺序
super 本质不是单纯的找父类,而是根据调用者的节点位置的广度优先顺序来的 '''
python--面向对象:继承的更多相关文章
- python 面向对象 继承 派生 组合
具体参考博客:http://www.cnblogs.com/linhaifeng/articles/6182264.html#_label12 一.面向对象 面向对象:对象与对象之间的相互交互,不可预 ...
- Python面向对象-继承和多态特性
继承 在面向对象的程序设计中,当我们定义一个class时候,可以从现有的class继承,新的class成为子类,被继承的class称为基类,父类或超类. 比如,编写一个名为Animal的class: ...
- Python面向对象继承案例
面向对象三大特性 封装 根据 职责 将 属性 和 方法 封装 到一个抽象的 类 中 继承 实现代码的重用,相同的代码不需要重复的编写 多态 不同的对象调用相同的方法,产生不同的执行结果,增加代码的灵活 ...
- Python 面向对象--继承,实现,依赖,关联,聚合,组合
一. 继承 继承指的是子类继承父类除私有内容以外的其他所有内容, 并且子类具有增加自己新内容的能力. 举例说明: class Animal: print("吃是动物的本能") cl ...
- Python面向对象 -- 继承和多态、获取对象信息、实例属性和类属性
继承和多态 继承的好处: 1,子类可以使用父类的全部功能 2,多态:当子类和父类都存在相同的方法时,子类的方法会覆盖父类的方法,即调用时会调用子类的方法.这就是继承的另一个好处:多态. 多态: 调用方 ...
- python面向对象 : 继承
一. 初识继承 继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类. 当我们在定义多个类的时候,发现要用到相同的方法或变量,如 ...
- Python面向对象----继承, 重载
1. 面向对象三大特性之继承. 继承的便捷是子类可以直接调用父类里面的方法和属性.(在强类型语言里面是只能调用公有成员), 不用重复的造轮子. 减少程序猿的负担.实现多态等上层结构 2. 父类代码 3 ...
- python 面向对象 继承
什么是继承 继承表达的是一种”是“的关系,比如人是动物 继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类 继承是基于抽象的结 ...
- python面向对象继承
class A(object):pass # 括号中可称为父类,基类,超类 class B:pass # 父类,基类,超类 class A_son(A,B):pass # 子类,派生类 class A ...
- 028.Python面向对象继承(单继承,多继承,super,菱形继承)
一 继承的概念 种类 单继承 多继承 至少两个类: 子类:一个类继承另外一个类,那么该类是子类(也叫作衍生类) 父类:另外一个,这个被继承的类,叫做父类(也叫作超类),object 在python中 ...
随机推荐
- UML指南系列——用例图
可以用用例来描述正在开发的系统想要实现的行为,而不必说明这些行为如何实现. 结构良好的用例只表示系统或者子系统的基本行为,而且既不过于笼统也不过于详细.
- 无法启动此程序 ,因为计算机中丢失MSVCP120.dll
1.文件丢失问题 无法启动此程序 ,因为计算机中丢失MSVCP120.dll 具体如下图所示: 等dll文件丢失,可以去下载 DirectX修复工具去修复即可 http://www.pc6.com/s ...
- Spark Core 1.3.1源码解析及个人总结
本篇源码基于赵星对Spark 1.3.1解析进行整理.话说,我不认为我这下文源码的排版很好,不能适应的还是看总结吧. 虽然1.3.1有点老了,但对于standalone模式下的Master.Worke ...
- Codeforces 1105E 最大独立集 状态DP 中途相遇法
题意:你有一个字符串, 有两种操作,一种是改变字符串,一种是某个用户询问这个字符串,如果一个用户每次查询字符串的时候都是他的用户名,他就会高兴.问最多有多少个用户会高兴? 题意:容易发现,在两个1操作 ...
- 【javascript闭包】转载一篇不错的解释,也有几个大牛的链接
初学闭包时一直以为很简单.但伴随对一个问题深入学习后,才算真正理解了闭包,同时也发现连<<JavaScript高级程序设计>>中都些不准确的地方. 我不准备从头介绍闭包的概念, ...
- 【LeetCode】Heap
[215] Kth Largest Element in an Array [Medium] 给个无序数组,返回第K大的数字. 方法1. 直接使用优先队列 priority_queue class S ...
- PHP中session存储及删除变量的方法
Session 变量保存的信息是单一用户的,并且可供应用程序中的所有页面使用.但是session会话信息是临时的,在用户离开网站后就会被删除.如果需要永久储存信息,就需要把数据存储在数据库中. < ...
- PHP实现上传视频的功能
首先前台HTML表单代码如下: <html> <head> <meta http-equiv="Content-Type" content=" ...
- JSTL标签的用法详解
在JSP中写Java代码是一件很恶心的事情,代码量少的话还可以,要是多的话,就蛋疼了,整个页面都是<% %>所以EL表达式和JSTL就应运而生了,这里我们注重讲解一下JSTL标签的使用: ...
- kafka为什么快?
为什么Kafka那么快 原创 2016-07-18 fireflyc 写程序的康德 网上有很多Kafka的测试文章,测试结果通常都是"吊打"其他MQ.感慨它的牛B之余我觉得必要仔细 ...