继承是一种的关系,和组合对比,组合是一种的关系,这两者都是解决代用重用问题的

继承

注意:继承不是遗传,在显示角度中,是通过对象抽象成类,再把这些类抽象成一个,就是父类。是自下而上的过程,在程序中是首先由父类,然后由类,之后才有对象,是自上而下的过程。


  1. class classparent1: #父类
  2. pass
  3. class classparent2:
  4. pass
  5. class useclass1(classparent1): # 单继承
  6. pass
  7. class useclass2(classparent1,classparent2): # 多继承
  8. pass
  9. print(useclass1.__bases__)
  10. print(useclass2.__bases__)

结果:

(<class 'main.classparent1'>,)

(<class 'main.classparent1'>, <class 'main.classparent2'>)

默认继承的是object类,Python3中都是新式类

类实例化

类实例化执行的时候首先从自己找,找不到从父类找。

继承与重用性

类中用的是父类的,不用重新写代码,实现了代码的复用。

  1. class Hero:
  2. def __init__(self,nickname,aggressivity,life_value):
  3. self.nickname = nickname
  4. self.aggressivity = aggressivity
  5. self.life_value =life_value
  6. def attack(self,enemy):
  7. enemy.life_value -= self.aggressivity
  8. class Garen(Hero):
  9. pass
  10. class Riven(Hero):
  11. camp = 'Noxus'
  12. g1 = Garen('garen',18,200) # 实例化
  13. r1 = Riven('garen',18,200)

派生

在子类中添加新的功能属性,派生首先是继承一个父类,定义一个新的,定义一个父类重名的,都会从子类自己的地方找。

  1. class Hero:
  2. def __init__(self,nickname,aggressivity,life_value):
  3. self.nickname = nickname
  4. self.aggressivity = aggressivity
  5. self.life_value =life_value
  6. def attack(self,enemy):
  7. enemy.life_value -= self.aggressivity
  8. class Garen(Hero):
  9. camp = 'Ddemacia'
  10. def atatack(self,enemy):
  11. pass
  12. def fire(self):
  13. print('%s is fireing' %self.nickname)
  14. class Riven(Hero):
  15. camp = 'Noxus'
  16. g1 = Garen('garen',18,200) # 实例化
  17. r1 = Riven('garen',18,200)
  18. g1.camp
  19. g1.atack(r1) # 调用自己的,派生出新的功能

在派生中调用

子类继承了父类的方法,然后想进行修改,注意了是基于原有的基础上修改,那么就需要在子类中调用父类的方法

方法1

使用的是父类的的函数功能

  1. class Hero:
  2. def __init__(self, nickname,aggressivity,life_value):
  3. self.nickname = nickname
  4. self.aggressivity = aggressivity
  5. self.life_value = life_value
  6. def attack(self, enemy):
  7. print('Hero attack')
  8. class Garen(Hero):
  9. camp = 'Demacia'
  10. def attack(self, enemy): #self=g1,enemy=r1
  11. # self.attack(enemy) #g1.attack() 这是绑定方法 进入递归出错
  12. Hero.attack(self,enemy) # 使用的是父类的attack 是函数,需要参数,selfs是上面传过来的
  13. print('from garen attack')
  14. def fire(self):
  15. print('%s is firing' % self.nickname)
  16. class Riven(Hero):
  17. camp = 'Noxus'
  18. g1 = Garen('garen', 18, 200)
  19. r1 = Riven('rivren', 18, 200)
  20. g1.attack(r1)

对父类的init函数进行重用


  1. class Hero:
  2. def __init__(self, nickname, aggressivity, life_value):
  3. self.nickname = nickname
  4. self.aggressivity = aggressivity
  5. self.life_value = life_value
  6. def attack(self, enemy):
  7. print('Hero attack')
  8. enemy.life_value -= self.aggressivity
  9. # print(Hero.__init__)
  10. # print(Hero.attack)
  11. class Garen(Hero):
  12. camp = 'Demacia'
  13. def __init__(self, nickname, aggressivity, life_value, script):
  14. Hero.__init__(self,nickname,aggressivity,life_value)
  15. self.script = script
  16. def attack(self, enemy): # self=g1,enemy=r1
  17. # self.attack(enemy) #g1.attack()
  18. Hero.attack(self, enemy)
  19. print('from garen attack')
  20. def fire(self):
  21. print('%s is firing' % self.nickname)
  22. # g1=Garen('garen',18,200) #Garen.__init__(g1,'garen',18,200)
  23. g1=Garen('garen',18,200,'人在塔在') #Garen.__init__(g1,'garen',18,200)
  24. print(g1.script)

方法2 Spper

python3 super

  1. #python3 super
  2. class People:
  3. def __init__(self,name,sex,age):
  4. self.name = name
  5. self.sex = sex
  6. self.age = age
  7. def walk(self):
  8. print("%s is walking"%self.name)
  9. class Chinese(People):
  10. country = 'china'
  11. def __init__(self,name,sex,age,language='Chinese'):
  12. super().__init__(name,sex,age) # python3中不需要再super内部传参数
  13. self.language = language
  14. def walk(self,x):
  15. super().walk() #
  16. print('子类的x',x) #
  17. c = Chinese('aaa','male',18)
  18. c.walk(123)

当你使用super()函数时,Python会在MRO列表上继续搜索下一个类。只要每个重定义的方法统一使用super()并只调用它一次,那么控制流最终会遍历完整个MRO列表,每个方法也只会被调用一次(注意注意注意:使用super调用的所有属性,都是从MRO列表当前的位置往后找,千万不要通过看代码去找继承关系,一定要看MRO列表

python2中的额super

  1. #python2 的super用法:
  2. # super(自己的类,self).父类的函数名
  3. # super只能适用于新式类
  4. class People(object): # python2中需要定义新式类
  5. def __init__(self,name,sex,age):
  6. self.name = name
  7. self.sex = sex
  8. self.age = age
  9. def walk(self):
  10. print("%s is walking"%self.name)
  11. class Chinese(People):
  12. country = 'china'
  13. def __init__(self,name,sex,age,language='Chinese'):
  14. super(Chinese,self).__init__(name,sex,age) # python3中不需要再super内部传参数
  15. self.language = language
  16. # def walk(self,x):
  17. # super().walk() #
  18. # print('子类的x',x) #
  19. c = Chinese('aaa','male',18)
  20. print(c.name,c.age,c.language)

组合

组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合

首先明确的是组合不是继承,是一种有的关系,是类与类之间的关系。

'''

不用组合的情况

'''

  1. class Teacher:
  2. def __init__(self,name,sex,course_name,course_price,course_peroid):
  3. self.name =name
  4. self.sex = sex
  5. self.course_name=course_name
  6. self.course_price = course_price
  7. self.course_peroid = course_peroid
  8. class Student:
  9. def __init__(self,name,sex,course_name,course_price,course_peroid):
  10. self.name = name
  11. self.sex = sex
  12. self.course_name = course_name
  13. self.course_price = course_price
  14. self.course_peroid = course_peroid
  15. t1 = Teacher('egon','male',)
  16. s1 = Student('cobile','name',)
  17. print(s1.course.name)
  18. print(t1.course.name)

使用类的情况

  1. # 使用组合重用代码
  2. class Course: # 新建了一个课程类
  3. def __init__(self,name,price,peroid):
  4. self.name = name
  5. self.price = price
  6. self.peroid = peroid
  7. class Teacher:
  8. def __init__(self,name,sex,course):
  9. self.name =name
  10. self.sex = sex
  11. self.course=course
  12. class Student:
  13. def __init__(self,name,sex,course):
  14. self.name = name
  15. self.sex = sex
  16. self.course = course
  17. python_obj = Course('python',15800,'7m') # 实例化课程类
  18. t1 = Teacher('egon','male',python_obj) # 直接用的是python_obj这个对象
  19. s1 = Student('cobile','name',python_obj)

接口与归一化设计##

继承有两种用途:

一:继承基类的方法,并且做出自己的改变或者扩展(代码重用)

二:声明某个子类兼容于某基类,定义一个接口类Interface,接口类中定义了一些接口名(就是函数名)且并未实现接口的功能,子类继承接口类,并且实现接口中的功能

接口继承实质上是要求“做出一个良好的抽象,这个抽象规定了一个兼容接口,使得外部调用者无需关心具体细节,可一视同仁的处理实现了特定接口的所有对象”——这在程序设计上,叫做归一化。

归一化使得高层的外部使用者可以不加区分的处理所有接口兼容的对象集合——就好象linux的泛文件概念一样,所有东西都可以当文件处理,不必关心它是内存、磁盘、网络还是屏幕(当然,对底层设计者,当然也可以区分出“字符设备”和“块设备”,然后做出针对性的设计:细致到什么程度,视需求而定)。

抽象类

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

抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化

如果说类是从一堆对象中抽取相同的内容而来的,那么抽象类就是从一堆类中抽取相同的内容而来的,内容包括数据属性和函数属性。

抽象类用到了模块abc,装饰器

  1. #抽象类
  2. import abc
  3. class Animal(metaclass=abc.ABCMeta):
  4. tag = '123'
  5. @abc.abstractclassmethod
  6. def run(self):
  7. pass
  8. @abc.abstractclassmethod
  9. def speak(self):
  10. pass
  11. class People(Animal):
  12. def run(self):
  13. pass
  14. def speak(self):
  15. pass
  16. peo1 = People()
  17. print(peo1.tag)

抽象类:本质还是类,与普通类额外的特点的是:加了装饰器的函数,子类必须实现他们

Python 继承、派生、组合、接口、抽象类的更多相关文章

  1. Python 继承和组合 接口

    #解决代码重用的问题,减少代码冗余 #继承是一种什么'是'什么的关系 class People: def __init__(self, name, age): # print('People.__in ...

  2. 初识JAVA(【面向对象】:pub/fri/pro/pri、封装/继承/多态、接口/抽象类、静态方法和抽象方法;泛型、垃圾回收机制、反射和RTTI)

    JAVA特点: 语法简单,学习容易 功能强大,适合各种应用开发:J2SE/J2ME/J2EE 面向对象,易扩展,易维护 容错机制好,在内存不够时仍能不崩溃.不死机 强大的网络应用功能 跨平台:JVM, ...

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

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

  4. Day 23 类的继承,派生,组合,菱形继承,多态与多态性

    类的继承 继承是一种新建类的方式,新建的类称为子类,被继承的类称为父类 继承的特性是:子类会遗传父类的属性 继承是类与类之间的关系 为什么用继承 使用继承可以减少代码的冗余 对象的继承 python中 ...

  5. python 继承与组合

    一.组合 #老师 课程 生日 class Course: def __init__(self,name,period,price): self.name = name self.period = pe ...

  6. Python开发基础-Day18继承派生、组合、接口和抽象类

    类的继承与派生 经典类和新式类 在python3中,所有类默认继承object,但凡是继承了object类的子类,以及该子类的子类,都称为新式类(在python3中所有的类都是新式类) 没有继承obj ...

  7. python基础之继承派生、组合、接口和抽象类

    类的继承与派生 经典类和新式类 在python3中,所有类默认继承object,但凡是继承了object类的子类,以及该子类的子类,都称为新式类(在python3中所有的类都是新式类) 没有继承obj ...

  8. Python(面向对象编程——2 继承、派生、组合、抽象类)

    继承与派生 ''' 继承:属于 组合:包含 一. 在OOP程序设计中,当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称 ...

  9. python面向对象编程 继承 组合 接口和抽象类

    1.类是用来描述某一类的事物,类的对象就是这一类事物中的一个个体.是事物就要有属性,属性分为 1:数据属性:就是变量 2:函数属性:就是函数,在面向对象里通常称为方法 注意:类和对象均用点来访问自己的 ...

  10. Py修行路 python基础 (十五)面向对象编程 继承 组合 接口和抽象类

    一.前提回忆: 1.类是用来描述某一类的事物,类的对象就是这一类事物中的一个个体.是事物就要有属性,属性分为 1:数据属性:就是变量 2:函数属性:就是函数,在面向对象里通常称为方法 注意:类和对象均 ...

随机推荐

  1. Java 普通方法和构造方法的区别

    构造方法: ①方法名和 类名相同 ②在方法名的前面没有返回值类型的声明 ③在方法中不能使用return语句返回一个值 ④在创建对象时,要调用new,如:book b1=new book(); ⑤当没有 ...

  2. jmeter+ant+jenkins实现自动化接口测试

    一.安装前准备 1.JDK:jdk-8u121-windows-x64 2.jmeter工具:apache-jmeter-2.13 3.ANT工具:apache-ant-1.9.7-bin 4.jen ...

  3. 剑指Offer的学习笔记(C#篇)-- 对称的二叉树

    题目描述 请实现一个函数,用来判断一颗二叉树是不是对称的.注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的. 一 . 题目分析 递归法. 一.空树判断,单独搞出来. 二.非空树. 递归:一 ...

  4. 微信分账功能与微信支付企业付款相关内容详解(payjs版)

    PAYJS开通微信分账功能以来,有很多同学咨询相关情况.很多同学关心有没有什么办法,可以让自己的商户号快速开通企业付款功能.这里就介绍下微信分账的具体相关内容,可以完美解决问题. 一.什么是微信分账? ...

  5. Java 基础类库

    与用户互动 1. 运行java程序的参数 public static void main(Stirng[] args) 这个方法是有JVM调用,因此用public static修饰,并且没有返回值,同 ...

  6. 安装redis服务器

    安装redis服务器 Windows环境下安装: 第一步:下载压缩包(地址:https://github.com/MicrosoftArchive/redis/releases) 第二步:解压并打开 ...

  7. NET Everywhere

    NET Everywhere 8月份已经发布了.NET Core 2.0, 大会Keynote 一开始花了大量的篇幅回顾.NET Core 2.0的发布,社区的参与度已经非常高.大会的主题是.NET ...

  8. 爬虫(Xpath)——爬tieba.baidu.com

    工具:python3 核心知识点: 1)lxml包不能用pip下载,因为里面有其他语言编写的文件 2)urlopen返回的请求是html文件,要使用 content = etree.HTML(html ...

  9. docker 的目录问题

    今天在使用Dockerfile制作镜像的时候,使用命令 :COPY aaa.sql /usr/test 下时, 总是报错 “INFO[0001] stat /var/lib/docker/aufs/m ...

  10. Linux下无法挂载U盘

    大概的错误信息是这样的: Error mounting /dev/sdb4 at /media/xxx/xx: Command-line`mount -t "ntfs" -o&qu ...