继承是创建新类的方式,新建的类可以继承多个父类(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--面向对象:继承的更多相关文章

  1. python 面向对象 继承 派生 组合

    具体参考博客:http://www.cnblogs.com/linhaifeng/articles/6182264.html#_label12 一.面向对象 面向对象:对象与对象之间的相互交互,不可预 ...

  2. Python面向对象-继承和多态特性

    继承 在面向对象的程序设计中,当我们定义一个class时候,可以从现有的class继承,新的class成为子类,被继承的class称为基类,父类或超类. 比如,编写一个名为Animal的class: ...

  3. Python面向对象继承案例

    面向对象三大特性 封装 根据 职责 将 属性 和 方法 封装 到一个抽象的 类 中 继承 实现代码的重用,相同的代码不需要重复的编写 多态 不同的对象调用相同的方法,产生不同的执行结果,增加代码的灵活 ...

  4. Python 面向对象--继承,实现,依赖,关联,聚合,组合

    一. 继承 继承指的是子类继承父类除私有内容以外的其他所有内容, 并且子类具有增加自己新内容的能力. 举例说明: class Animal: print("吃是动物的本能") cl ...

  5. Python面向对象 -- 继承和多态、获取对象信息、实例属性和类属性

    继承和多态 继承的好处: 1,子类可以使用父类的全部功能 2,多态:当子类和父类都存在相同的方法时,子类的方法会覆盖父类的方法,即调用时会调用子类的方法.这就是继承的另一个好处:多态. 多态: 调用方 ...

  6. python面向对象 : 继承

    一. 初识继承 继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类. 当我们在定义多个类的时候,发现要用到相同的方法或变量,如 ...

  7. Python面向对象----继承, 重载

    1. 面向对象三大特性之继承. 继承的便捷是子类可以直接调用父类里面的方法和属性.(在强类型语言里面是只能调用公有成员), 不用重复的造轮子. 减少程序猿的负担.实现多态等上层结构 2. 父类代码 3 ...

  8. python 面向对象 继承

    什么是继承 继承表达的是一种”是“的关系,比如人是动物 继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类 继承是基于抽象的结 ...

  9. python面向对象继承

    class A(object):pass # 括号中可称为父类,基类,超类 class B:pass # 父类,基类,超类 class A_son(A,B):pass # 子类,派生类 class A ...

  10. 028.Python面向对象继承(单继承,多继承,super,菱形继承)

    一 继承的概念 种类 单继承 多继承 至少两个类: 子类:一个类继承另外一个类,那么该类是子类(也叫作衍生类) 父类:另外一个,这个被继承的类,叫做父类(也叫作超类),object 在python中 ...

随机推荐

  1. emacs-w3m查看html帮助手册

    emacs-w3m查看html帮助手册 */--> code {color: #FF0000} pre.src {background-color: #002b36; color: #83949 ...

  2. 最全的chrome显示www和https方法(全版本)

    78以前的老版本 设置如下参数 chrome://flags/#omnibox-ui-hide-steady-state-url-scheme chrome://flags/#omnibox-ui-h ...

  3. vps被封逃逸_v2+cloudflare+websocket+tls+nginx

    每逢重大节日,总有那么一大部分vps凉凉,以下为能正经正常使用vps,无奈之举,此法由于多层代理,夜间速度会有影响,白天感受不明显. 由于博客园内容审查,v2_ray 中间的 下划线为分隔符,相关链接 ...

  4. LeetCode Array Easy 122. Best Time to Buy and Sell Stock II

    Description Say you have an array for which the ith element is the price of a given stock on day i. ...

  5. Redis 管道(pipeline)

  6. Exist/In 使用

    exists表示()内子查询语句返回结果不为空说明where条件成立就会执行主sql语句,如果为空就表示where条件不成立,sql语句就 不会执行.not exists和exists相反,子查询语句 ...

  7. 使用Turbine对集群进行监控

    为什么要使用Turbine Turbine是聚合服务器发送事件流数据的一个工具,hystrix的监控中,只能监控单个节点,实际生产中都为集群,因此可以通过turbine来监控集群下hystrix的me ...

  8. Codeforces - 1139D - Steps to One (概率DP+莫比乌斯反演)

    蒟蒻数学渣呀,根本不会做. 解法是参考 https://blog.csdn.net/xs18952904/article/details/88785210 这位大佬的. 状态的设计和转移如上面博客一样 ...

  9. JavaWeb开发之二《JSP + Tomcat的第一个程序“Hello World”》

    搬以前写的博客[2014-12-10 22:41] 前一篇博客讲了Tomcat环境搭建,于是开始第一个“Hello JSP”程序. 服务器环境搭建好之后,我们开始写自己的网站,这里简单的写一个没有后台 ...

  10. windows线程函数必须为全局函数或者静态函数(转)

    调用CreateThread(...)创建线程时要指定所创建线程的入口函数,此入口函数只能是全局函数或者类的静态成员函数. 全局函数很容易理解,但如果是类的成员函数则必须是静态成员函数,为何, 因为类 ...