一文了解什么是Python面向对象中的继承-Python教程

资源魔 30 0

一、甚么是承继?

承继指的是类与类之间的关系,是一种甚么是甚么的关系,性能之一就是用来处理代码重用成绩。

承继是一种创立新类的形式,正在python中,新建的类能够承继一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类,承继又分为单承继以及多承继。

class ParentClass1: #界说父类
    pass
class ParentClass2: #界说父类
    pass
class SubClass1(ParentClass1): #单承继,基类是ParentClass1,派生类是SubClass
    pass
class SubClass2(ParentClass1,ParentClass2): #python支持多承继,用逗号分离隔多个承继的类
    pass
print(Son1.__bases__)  # 查看一切承继的父类
print(Son2.__bases__)
===============
(<class '__main__.Father1'>,)
(<class '__main__.Father1'>, <class '__main__.Father2'>)

二、承继与形象

形象分红两个条理:

1.将奥巴马以及梅西这俩工具比拟像的局部抽取成类;

2.将人,猪,狗这三个类比拟像的局部抽取成父类。

形象最次要的作用是划分种别(能够隔离存眷点,升高复杂度)

1566984641(1).png

承继:

是基于形象的后果,经过编程言语去完成它,一定是先经验形象这个进程,能力经过承继的形式去表白出形象的构造。

形象只是剖析以及设计的进程中,一个举措或许说一种技术,经过形象能够失去类。

1566984624(1).png

class animal():   # 界说父类
    country  =  'china'     # 这个叫类的变量
    def __init__(self,name,age):
        self.name=name   # 这些又叫数据属性
        self.age=age
    def walk(self):         # 类的函数,办法,静态属性
        print('%s is walking'%self.name)
    def say(self):
        pass
class people(animal):  # 子类承继父类
    pass
class pig(animal):    # 子类承继父类
    pass
class dog(animal):  # 子类承继父类
    pass
aobama=people('aobama',60)   # 实例化一个工具
print(aobama.name)
aobama.walk()
===================
aobama
aobama is walking

三、派生

1.正在父类的根底上孕育发生子类,孕育发生的子类就叫做派生类。

2.父类里不的办法,正在子类中有了,这样的办法就叫做派生办法。

3.父类里有,子类也有的办法,就叫做办法的重写(就是把父类里的办法重写了)。

相干保举:《Python视频教程》

例1

class Hero:
    def __init__(self, nickname,
                 aggressivity,
                 life_value):
        self.nickname = nickname
        self.aggressivity = aggressivity
        self.life_value = life_value
    def attack(self, enemy):
        enemy.life_value -= self.aggressivity
class Garen(Hero):   # 子类承继  hero 父类
    camp='Demacia'   # 子类衍生出的变量
    def attack(self, enemy):   # 跟父类的 attack 重名,工具挪用的时分以子类的为准
        pass
    def fire(self):    # 父类不 fire,这里 fire 属于派生进去的货色
        print('%s is firing' %self.nickname)
class Riven(Hero):
    camp='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()

四、组合与重用性

重用性:

形式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课程,传授有先生s一、s二、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()

五、接口与归一化设计

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('过程数据的读取办法')

下面的代码只是看起来像接口,其实并无起到接口的作用,子类齐全能够不必去完成接口,这就用到了形象类。

六、形象类

子类必需承继形象类的办法,否则报错。

甚么是形象类?

与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面向工具中的承继的具体内容,更多请存眷资源魔其它相干文章!

标签: 面向对象 继承 Python python教程 python编程 python使用问题

抱歉,评论功能暂时关闭!