python2中面向对象的多继承是,python中继承的概念

  python2中面向对象的多继承是,python中继承的概念

  

  1、什么是继承?

  继承是指类之间的关系,是什么就是什么。它的功能之一就是解决代码重用的问题。

  继承是创建新类的一种方式。在python中,一个新类可以继承一个或多个父类,可以称为基类或超类,一个新类称为派生类或子类。继承可分为单一继承和多重继承。

  Classparentclass13360 #定义父类

  及格

  Classparentclass 23360 #定义父类

  及格

  class SubClass 1(ParentClass1)3360 #单继承,基类是parent class 1,派生类是subclass。

  及格

  Classsubclass 2 (parent class1,parent class2) : # Python支持多重继承,多个继承的类之间用逗号分隔。

  及格

  打印(Son1。__bases__) #查看所有继承的父类

  打印(Son2。__bases__)

  ===============

  (class __main__.Father1 ,)

  (class __main__.Father1 ,class _ _ main _ _ . father 2 )2、继承与抽象

  抽象分为两个层次:

  1.将奥巴马和梅西相似的部分提取到类中;

  2.将人、猪、狗的相似部分提取到父类中。

  抽象的主要作用是划分类别(可以隔离关注点,降低复杂度)。

  继承:

  它是抽象的结果。要通过编程语言来实现,必须经过抽象的过程,才能通过继承来表达抽象的结构。

  只是在抽象分析和设计的过程中,一个动作或者一个技能可以通过抽象得到一个类。

  Class animal(): #定义父类

  国家=中国 #这个变量叫做阶级

  def __init__(自己,姓名,年龄):

  Self.name=name #这些也称为数据属性。

  年龄=年龄

  def walk(self): #类的函数、方法和动态属性

  打印(“%s”正在遍历“%self.name”)

  def say(self):

  及格

  类人(动物): #子类继承父类。

  及格

  类猪(动物): #子类继承父类。

  及格

  类狗(动物): #子类继承父类。

  及格

  奥巴马=人民(一个奥巴马,60) #实例化一个对象

  打印(奥巴马.姓名)

  奥巴马.沃克()

  ===================

  奥巴马

  奥巴马正在走3、派生

  1.基于父类生成子类,生成的子类称为派生类。

  2.不存在于父类中,但存在于子类中的方法。这种方法称为派生方法。

  3.父类和子类中都有方法,这叫做方法重写(也就是重写父类中的方法)。

  相关:《Python视频教程》

  示例1

  班级英雄:

  def __init__(自己,昵称,

  侵略性,

  人生_价值):

  自我昵称=昵称

  自我攻击性=攻击性

  自我生命价值=生命价值

  防御攻击(自己,敌人):

  敌人.生命值-=自我.攻击性

  类garen (hero) 3360 #子类继承hero父类。

  从子类camp=Demacia #派生的变量。

  DEF attack (self,enemy) 3360 #与父类的攻击同名,对象由子类调用。

  及格

  DEF fire (self) 3360 #父类没有fire,这里fire是一个派生词。

  打印( %s正在激发 %self.nickname )

  瑞文级(英雄):

  大约

  mp='Noxus'

  g1=Garen('garen',18,200)

  r1=Riven('rivren',18,200)

  # print(g1.camp)

  # print(r1.camp)

  # g1.fire()

  g1.attack(g1)例2

  

class Hero:

   def __init__(self, nickname,aggressivity,life_value):

   self.nickname = nickname

   self.aggressivity = aggressivity

   self.life_value = life_value

   def attack(self, enemy):

   print('Hero attack')

  class Garen(Hero):

   camp = 'Demacia'

   def attack(self, enemy): #self=g1,enemy=r1

   # self.attack(enemy) #g1.attack(r1),这里相当于无限递归

   Hero.attack(self,enemy) # 引用 父类的 attack,对象会去跑 父类的 attack

   print('from garen attack') # 再回来这里

   def fire(self):

   print('%s is firing' % self.nickname)

  class Riven(Hero):

   camp = 'Noxus'

  g1 = Garen('garen', 18, 200)

  r1 = Riven('rivren', 18, 200)

  g1.attack(r1)

  # print(g1.camp)

  # print(r1.camp)

  # g1.fire()

4、组合与重用性

  重用性:

  方式1:不通过继承的方式重用属性,指名道姓的使用哪个类的属性。

  

class Hero:

   def __init__(self,nickname,gongji,life):

   self.nickname=nickname

   self.gongji=gongji

   self.life=life

   def attack(self,obj):

   print('from Hero attack')

  class Garen:

   def __init__(self,nickname,gongji,life,script):

   Hero.__init__(self,nickname,gongji,life) # 这里引用Hero类的 init,不用再自己从新定义一遍 init

   self.script=script # 父类 init 没有 script,这里是新加进来的属性

   def attack(self,obj): # 在这里自己定义新的 attack,不再使用父类的 attack

   print('from Garen attack')

   def fire(self): # 在这里定义新的功能

   print('from Garen fire')

  g1=Garen('garen',18,200,'人在塔在')

  print(g1.script)

  人在塔在

提示:用已经有的类建立一个新的类,这样就重用了已经有的软件中的一部分甚至大部分,大大省了编程工作量,这就是常说的软件重用,不仅可以重用自己的类,也可以继承别人的,比如标准库,来定制新的数据类型,这样就是大大缩短了软件开发周期,对大型软件开发来说,意义重大。

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

  方式2:通过继承

  例1

  

class Hero():

   def __init__(self, nickname, gongji, life):

   self.nickname = nickname

   self.gongji = gongji

   self.life = life

   def attack(self, obj):

   print('from Hero attack')

   obj.life -= self.gongji

  class Garen(Hero): # 使用 super方式需要继承

   camp = 'Demacia'

   def __init__(self, nickname, gongji, life):

   super().__init__(nickname, gongji, life)

   def attack(self, obj): # 在这里自己定义新的 attack,不再使用父类的 attack

   super(Garen, self).attack(obj) # PY3中super可以不给参数,PY2中第一个参数必须是自己的类,self,可以使用

   父类的方法,方法需要给参数就给参数

   def fire(self): # 在这里定义新的功能

   print('from Garen fire')

  g1 = Garen('garen1', 18, 200)

  g2 = Garen('garen2', 20, 100)

  print(g2.life)

  g1.attack(g2)

  print(g2.life)

  100

  from Hero attack

  82

例2

  

class A:

   def f1(self):

   print('from A')

   super().f1()

   # 这种不需要继承也可以使用到 super,为什么,要看 C的 MRO表

  class B:

   def f1(self):

   print('from B')

  class C(A,B):

   pass

  print(C.mro())

  #[<class '__main__.C'>,

  # <class '__main__.A'>,

  # <class '__main__.B'>, # B在A的后面,当A指定 super().f1 会找到 B的 f1

  # <class 'object'>]

  c=C()

  c.f1()

组合:

  软件重用的重要方式除了继承之外还有另外一种方式,即:组合。

  组合:一个对象的数据属性是另一个对象,称为组合。

  

class Equip: #武器装备类

   def fire(self):

   print('release Fire skill')

  class Riven: #英雄Riven的类,一个英雄需要有装备,因而需要组合Equip类

   camp='Noxus'

   def __init__(self,nickname):

   self.nickname=nickname

   self.equip=Equip() #用Equip类产生一个装备,赋值给实例的equip属性

  r1=Riven('锐雯雯')

  r1.equip.fire() #可以使用组合的类产生的对象所持有的方法

  release Fire skill

组合的方式:

  组合与继承都是有效地利用已有类的资源的重要方式。但是二者的概念和使用场景皆不同。

  1.继承的方式

  通过继承建立了派生类与基类之间的关系,它是一种'是'的关系,比如白马是马,人是动物。

  当类之间有很多相同的功能,提取这些共同的功能做成基类,用继承比较好,比如老师是人,学生是人

  2.组合的方式

  用组合的方式建立了类与组合的类之间的关系,它是一种‘有’的关系,比如教授有生日,教授教python和linux课程,教授有学生s1、s2、s3...

  

class People:

   def __init__(self,name,age,sex):

   self.name=name

   self.age=age

   self.sex=sex

  class Course:

   def __init__(self,name,period,price):

   self.name=name

   self.period=period

   self.price=price

   def tell_info(self):

   print('<%s %s %s>' %(self.name,self.period,self.price))

  class Teacher(People):

   def __init__(self,name,age,sex,job_title):

   People.__init__(self,name,age,sex)

   self.job_title=job_title

   self.course=[]

   self.students=[]

  class Student(People):

   def __init__(self,name,age,sex):

   People.__init__(self,name,age,sex)

   self.course=[]

  egon=Teacher('egon',18,'male','沙河霸道金牌讲师')

  s1=Student('牛榴弹',18,'female')

  python=Course('python','3mons',3000.0)

  linux=Course('python','3mons',3000.0)

  #为老师egon和学生s1添加课程

  egon.course.append(python)

  egon.course.append(linux)

  s1.course.append(python)

  #为老师egon添加学生s1

  egon.students.append(s1)

  #使用

  for obj in egon.course:

   obj.tell_info()

5、接口与归一化设计

  a、为何要用接口?

  接口提取了一群类共同的函数,可以把接口当做一个函数的集合。

  然后让子类去实现接口中的函数。

  这么做的意义在于归一化,什么叫归一化,就是只要是基于同一个接口实现的类,那么所有的这些类产生的对象在使用时,从用法上来说都一样。

  归一化的好处在于:

  归一化让使用者无需关心对象的类是什么,只需要的知道这些对象都具备某些功能就可以了,这极大地降低了使用者的使用难度。

  

class Interface:#定义接口Interface类来模仿接口的概念,python中压根就没有interface关键字来定义一个接口。

   def read(self): #定接口函数read

   pass

   def write(self): #定义接口函数write

   pass

  class Txt(Interface): #文本,具体实现read和write

   def read(self):

   print('文本数据的读取方法')

   def write(self):

   print('文本数据的读取方法')

  class Sata(Interface): #磁盘,具体实现read和write

   def read(self):

   print('硬盘数据的读取方法')

   def write(self):

   print('硬盘数据的读取方法')

  class Process(Interface):

   def read(self):

   print('进程数据的读取方法')

   def write(self):

   print('进程数据的读取方法')

上面的代码只是看起来像接口,其实并没有起到接口的作用,子类完全可以不用去实现接口,这就用到了抽象类。

  6、抽象类

  子类必须继承抽象类的方法,不然报错。

  什么是抽象类?

  与java一样,python也有抽象类的概念但是同样需要借助模块实现,抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化

  为什么要有抽象类?

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

  比如我们有香蕉的类,有苹果的类,有桃子的类,从这些类抽取相同的内容就是水果这个抽象的类,你吃水果时,要么是吃一个具体的香蕉,要么是吃一个具体的桃子。你永远无法吃到一个叫做水果的东西。

  从设计角度去看,如果类是从现实对象抽象而来的,那么抽象类就是基于类抽象而来的。

  从实现角度来看,抽象类与普通类的不同之处在于:抽象类中只能有抽象方法(没有实现功能),该类不能被实例化,只能被继承,且子类必须实现抽象方法。

  抽象类与接口

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

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

  例1

  

import abc

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

  class Animal(metaclass=abc.ABCMeta): # 抽象类是用来被子类继承的,不是用来实例化的

   tag='123123123123123'

   @abc.abstractmethod # 如果子类没有我这个函数,主动抛出异常

   def run(self):

   pass

   @abc.abstractmethod

   def speak(self):

   pass

  class People(Animal):

   def run(self): # 子类必须有抽象类里的装饰器下面的函数

   pass

   def speak(self):

   pass

  peo1=People() # 实例化出来一个人

  print(peo1.tag)

例2

  

#_*_coding:utf-8_*_

  __author__ = 'Linhaifeng'

  #一切皆文件

  import abc #利用abc模块实现抽象类

  class All_file(metaclass=abc.ABCMeta):

   all_type='file'

   @abc.abstractmethod #定义抽象方法,无需实现功能

   def read(self):

   '子类必须定义读功能'

   pass

   @abc.abstractmethod #定义抽象方法,无需实现功能

   def write(self):

   '子类必须定义写功能'

   pass

  # class Txt(All_file):

  # pass

  #

  # t1=Txt() #报错,子类没有定义抽象方法

  class Txt(All_file): #子类继承抽象类,但是必须定义read和write方法

   def read(self):

   print('文本数据的读取方法')

   def write(self):

   print('文本数据的读取方法')

  class Sata(All_file): #子类继承抽象类,但是必须定义read和write方法

   def read(self):

   print('硬盘数据的读取方法')

   def write(self):

   print('硬盘数据的读取方法')

  class Process(All_file): #子类继承抽象类,但是必须定义read和write方法

   def read(self):

   print('进程数据的读取方法')

   def write(self):

   print('进程数据的读取方法')

  wenbenwenjian=Txt()

  yingpanwenjian=Sata()

  jinchengwenjian=Process()

  #这样大家都是被归一化了,也就是一切皆文件的思想

  wenbenwenjian.read()

  yingpanwenjian.write()

  jinchengwenjian.read()

  print(wenbenwenjian.all_type)

  print(yingpanwenjian.all_type)

  print(jinchengwenjian.all_type)

以上就是一文了解什么是Python面向对象中的继承的详细内容,更多请关注盛行IT软件开发工作室其它相关文章!

  

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: