前两天我们认识了面向对象也对面向对象有了初步的认识今天我们先会说一点组合的进阶,今天重点是继承。

本篇导航:

一、组合

组合只有一个例子因为组合只作为上一章的补充内容

#老师 课程 生日
class Course:
def __init__(self,name,period,price):
self.name = name
self.period = period
self.price = price class Birth:
def __init__(self,year,month,day):
self.year = year
self.month = month
self.day = day class Teacher:
def __init__(self,name,salary,boy_friend,python):
self.name = name
self.salary = salary
self.bf = boy_friend
self.course = python python = Course('python','6 months',20000) egg = Teacher('egon',200,'yuan',python)
print(egg.bf)
print(egg.name)
print(egg.course.name) egg_birth = Birth(1965,2,2)
print(egg_birth.year)
egg.birth = egg_birth
print('***',egg.birth.year)

组合


二、继承

1、何为继承

继承,面向对象中的继承和现实生活中的继承相同,即:子可以继承父的内容。

面向对象编程语言的一个主要功能就是“继承”。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。

通过继承创建的新类称为“子类”或“派生类”。被继承的类称为“基类”、“父类”或“超类”。继承的过程,就是从一般到特殊的过程。

class ParentClass1: #定义父类
pass class ParentClass2: #定义父类
pass class SubClass1(ParentClass1): #单继承,基类是ParentClass1,派生类是SubClass
pass class SubClass2(ParentClass1,ParentClass2): #python支持多继承,用逗号分隔开多个继承的类
pass

继承

查询继承

SubClass1.__bases__ #查看所有继承的父类

如果没有指定基类,python的类会默认继承object类,object是所有python类的基类

2、继承与抽象

继承 是从大范围到小范围

抽象 小范围到大范围

抽象即抽取类似或者说比较像的部分。

继承:是基于抽象的结果,通过编程语言去实现它,肯定是先经历抽象这个过程,才能通过继承的方式去表达出抽象的结构。

3、继承与重用性

class Animal:
'''
人和狗都是动物,所以创造一个Animal基类
'''
def __init__(self, name, aggressivity, life_value):
self.name = name # 人和狗都有自己的昵称;
self.aggressivity = aggressivity # 人和狗都有自己的攻击力;
self.life_value = life_value # 人和狗都有自己的生命值; def eat(self):
print('%s is eating'%self.name) class Dog(Animal):
pass class Person(Animal):
pass egg = Person('egon',10,1000)
ha2 = Dog('二愣子',50,1000)
egg.eat()
ha2.eat()

代码重用

用已经有的类建立一个新的类,这样就重用了已经有的类中的一部分甚至大部分,大大节省了编程工作量,这就是重用

4、派生

当然子类也可以添加自己新的属性或者在自己这里重新定义这些属性(不会影响到父类),需要注意的是,一旦重新定义了自己的属性且与父类重名,那么调用新增的属性时,就以自己为准了。

class Animal:
'''
人和狗都是动物,所以创造一个Animal基类
'''
def __init__(self, name, aggressivity, life_value):
self.name = name # 人和狗都有自己的昵称;
self.aggressivity = aggressivity # 人和狗都有自己的攻击力;
self.life_value = life_value # 人和狗都有自己的生命值; def eat(self):
print('%s is eating'%self.name) class Dog(Animal):
'''
狗类,继承Animal类
'''
def bite(self, people):
'''
派生:狗有咬人的技能
:param people:
'''
people.life_value -= self.aggressivity class Person(Animal):
'''
人类,继承Animal
'''
def attack(self, dog):
'''
派生:人有攻击的技能
:param dog:
'''
dog.life_value -= self.aggressivity egg = Person('egon',10,1000)
ha2 = Dog('二愣子',50,1000)
print(ha2.life_value)
print(egg.attack(ha2))
print(ha2.life_value)

派生

像ha2.life_value之类的属性引用,会先从实例中找life_value然后去类中找,然后再去父类中找...直到最顶级的父类。

子类执行父类的方法可以直接用super方法,或者用调用普通函数的方式,即:类名.func()

class Animal:      #父类  基类  超类
def __init__(self,name,life_value,aggr):
self.name = name
self.life_value = life_value
self.aggr = aggr #攻击力
def eat(self):
self.life_value += 10 class Person(Animal): #子类 派生类
def __init__(self,money,name,life_value,aggr):
super().__init__(name,life_value,aggr)
self.money = money #派生属性 def attack(self,enemy): #人的派生方法
enemy.life_value -= self.aggr class Dog(Animal): #子类 派生类
def __init__(self,breed,name,life_value,aggr):
#Animal.__init__(self,name,life_value,aggr) #让子类执行父类的方法,就是父类名.方法名(参数),连self也得传
super().__init__(name,life_value,aggr) #super关键字——新式类
#super(Dog,self).__init__(name,life_value,aggr) #super关键字——新式类
self.breed = breed
def bite(self,person): #狗的派生方法
person.life_value -= self.aggr def eat(self): # 父类方法的重写
super().eat()
print('dog is eating~~~ ') ha2 = Dog('牛头梗','旺财',20000,100)
print(ha2.life_value)
ha2.eat()
print(ha2.life_value)
# super(Dog,ha2).eat() #调用父类的
print(ha2.life_value)

super

5、小结

在继承中
继承的语法:
class 类名(父类名):
想在子类中实现调用父类的方法
在类内 ——super(子类名,self).方法名()
在类外面 ——super(子类名,对象名).方法名()
如果不指定继承的父类,默认继承object
子类可以使用父类的所有属性和方法
如果子类有自己的方法就执行自己的的
如果是子类没有的方法就执行父类的
如果子类父类都没有这个方法就报错 继承、抽象、派生
继承 是从大范围到小范围
抽象 小范围到大范围
派生 就是在父类的基础上又产生子类——派生类
父类里没有的 但子类有的 ——派生方法,派生属性
方法的重写
父类里有的方法,在子类里重新实现

小结


三、抽象类与接口类

抽象类的本质还是类,指的是一组类的相似性,包括数据属性(如all_type)和函数属性(如read、write),而接口只强调函数属性的相似性。

抽象类是一个介于类和接口直接的一个概念,同时具备类和接口的部分特性,可以用来实现归一化设计

在python中,并没有接口类这种东西,即便不通过专门的模块定义接口,我们也应该有一些基本的概念。

1、多继承问题

在继承抽象类的过程中,我们应该尽量避免多继承;

而在继承接口的时候,我们反而鼓励你来多继承接口

接口隔离原则:
使用多个专门的接口,而不使用单一的总接口。即客户端不应该依赖那些不需要的接口。

2、方法的实现

1)在抽象类中,我们可以对一些抽象方法做出基础实现;

from abc import ABCMeta,abstractmethod
class Animal(metaclass=ABCMeta):
@abstractmethod
def eat(self):
print('打开粮食的袋子')
print('放一个吃饭的碗')
print('把粮食倒在碗里') @abstractmethod
def sleep(self):
pass class Dog(Animal):
def eat(self):
super().eat()
print('dog is eating') def sleep(self):
print('dog is sleeping') d = Dog()
d.eat()

抽象类

抽象类:

抽象: 从小范围到大范围

2)而在接口类中,任何方法都只是一种规范,具体的功能需要子类实现

from abc import ABCMeta,abstractmethod
class Payment(metaclass = ABCMeta): #metaclass --> 元类
@abstractmethod
def pay(self,money):pass class Applepay(Payment):
def pay(self,money):
print('apple pay 支付了%s'%money) class Alipay(Payment):
def pay(self,money):
print('支付宝 支付了%s'%money) class Wechatpay(Payment):
def fuqian(self,money):
print('微信支付了%s'%money) def payment(pay_obj,money):
pay_obj.pay(money) apple1 = Applepay()
ali1 = Alipay()
wechat1 = Wechatpay()
payment(wechat1,200)

接口类

接口类:

约束继承接口类的子类必须实现被abstractmethod装饰的方法

在接口类中不要做实现(不要出现函数体)

接口类不能被实例化

3、小结

1)当几个子类的父类 有相同的功能需要被实现的时候 就用抽象类

当几个子类 有相同的功能 但是实现各不相同的时候 就用接口类

抽象类和接口类的本质作用:约束

2)抽象类

在Python里 默认是有的

父类的方法 子类必须实现

抽象类 不能被实例化

抽象类内的方法 可以被简单实现

3)接口类(在抽象类的基础上)

在python里 默认是没有的

接口类中的方法 不能被实现

原则:抽象类最好不要用多继承,而接口类可以


四、钻石继承

继承顺序

python如果继承了多个类寻找方法有两个方法深度优先(经典类)和广度优先(新式类),而python3中没有经典类了,所以我们不用考虑多重情况。

class A(object):
def test(self):
print('from A') class B(A):
def test(self):
print('from B') class C(A):
def test(self):
print('from C') class D(B):
def test(self):
print('from D') class E(C):
def test(self):
print('from E') class F(D,E):
# def test(self):
# print('from F')
pass
print(F.mro())
#这个属性可以查看继承属性 #新式类继承顺序:F->D->B->E->C->A
#经典类继承顺序:F->D->B->A->E->C
#python3中统一都是新式类
#pyhon2中才分新式类与经典类

继承顺序

上面这个图这是让大家了解一下,平时可以直接使用mro()方法查看

python进阶(5):组合,继承的更多相关文章

  1. python基础之组合继承多态

    组合 1.什么是组合 组合就是一个类的对象具备一个指向另外一个类的对象的属性 2.为何用组合 组合可以减少代码冗余 3.如何使用 class People: def __init__(self,nam ...

  2. Python进阶-继承中的MRO与super

    Python进阶-继承中的MRO与super 写在前面 如非特别说明,下文均基于Python3 摘要 本文讲述Python继承关系中如何通过super()调用"父类"方法,supe ...

  3. Python进阶(十五)----面向对象之~继承(单继承,多继承MRO算法)

    Python进阶(十五)----面向对象之~继承 一丶面向对象的三大特性:封装,继承,多态 二丶什么是继承 # 什么是继承 # b 继承 a ,b是a的子类 派生类 , a是b的超类 基类 父类 # ...

  4. python基础之类的继承与派生、组合、接口与归一化设计、抽象类、子类中调用父类方法

    一.什么是继承 继承是一种创建新的类的方式,新建的类可以继承自一个或者多个父类,原始类称为基类或超类,新建的类称为派生类或子类. 派生:子类继承了父类的属性,然后衍生出自己新的属性,如果子类衍生出的新 ...

  5. python开发面向对象基础:组合&继承

    一,组合 组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合      人类装备了武器类就是组合 1.圆环,将圆类实例后传给圆环类 #!/usr/bin/env python #_*_ ...

  6. python进阶03 继承

    python进阶03 继承 一.继承 课堂练习:假设你正在参与一个魔幻类角色游戏的开发,公司需要腻味这个游戏设计两个角色的类: a.剑士 属性:1.角色名:2.角色等级:3.生命值:4.攻击力 行为: ...

  7. Python进阶(十六)----面向对象之~封装,多态,鸭子模型,super原理(单继承原理,多继承原理)

    Python进阶(十六)----面向对象之~封装,多态,鸭子模型,super原理(单继承原理,多继承原理) 一丶封装 , 多态 封装:            将一些东西封装到一个地方,你还可以取出来( ...

  8. Python 入门 之 类的三大关系(依赖 / 组合/ 继承关系)

    Python 入门 之 类的三大关系(依赖 / 组合/ 继承关系) 在面向对象的中,类与类之间存在三种关系:依赖关系.组合关系.继承关系. 1.依赖关系:将一个类的类名或对象当做参数传递给另一个函数被 ...

  9. C++进阶--代码复用 继承vs组合

    //############################################################################ /* * 代码复用: 继承 vs 组合 * ...

随机推荐

  1. Example012点击修改属性

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. Vim正则通配符使用心得

    目的 实现替换 c f[i][j][k] -> f[k][i][j] f[i + 1][j][k] -> f[k][i + 1][j] f[i + 1][j + NY][k] -> ...

  3. Openfire插件开发图解

    概述 Openfire插件开发是Openfire的精髓之一,支持插件热插拔,还可以方便的在web端进行管理插件.插件分为两种,一种是以服务为主的控制台插件,一种是包括页面或对外开放Servlet接口. ...

  4. Django+MySQL开发项目:内容管理系统cms(一)

    Baker-Miller Pink被科学方法证实可以平静情绪并且抑制食欲的颜色,具有amazing的效果.基百里面说实验结果表明该颜色具有: "a marked effect on lowe ...

  5. 初学spring boot踩过的坑

    一.搭建spring boot环境 maven工程 pom文件内容 <project xmlns="http://maven.apache.org/POM/4.0.0" xm ...

  6. 在ubuntu14.04上安装mono4.4 + jexus + mvc6

    0.准备工作 在/usr下建立一个文件夹,方便管理源码 cd /usr mkdir opensource cd opensource 安装vim(文本编辑器,不习惯用vim可以换成其他的) apt-g ...

  7. [随笔]_ELVE_git命令复习

    mkdir: XX (创建一个空目录 XX指目录名) pwd: 显示当前目录的路径. git init 把当前的目录变成可以管理的git仓库,生成隐藏.git文件. git add XX 把xx文件添 ...

  8. voa 2015 / 4 / 18

    Words in This Story gerund - n. an English noun formed from a verb by adding -ing infinitive - n. th ...

  9. DELPHI XE5安装

    1.安装XE5 2. HNFJ-DPADCW-BDWCFU-FPNN QDF4-CTSDHV-RDFCFE-FEAN HNFK-BCN8NN-78N53D-H4RS 破解补丁使用方法: (1).复制压 ...

  10. 动态数组ArrayList的使用

    1.定义类 package com.realhope.rmeal.bean; /** * * @author Wucy * 菜谱类 */ public class Menu{ private Inte ...