类别:Python / 日期:2019-12-02 / 浏览:115 / 评论:0

1、什么是继续?

继续指的是类与类之间的关联,是一种什么是什么的关联,功用之一就是用来处理代码重用题目。

继续是一种竖立新类的体式格局,在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'>)

2、继续与笼统

笼统分红两个条理:

1.将奥巴马和梅西这俩对象比较像的部份抽取成类;

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

笼统最主要的作用是分别种别(能够断绝关注点,下降复杂度)

继续:

是基于笼统的效果,经由历程编程言语去完成它,肯定是先阅历笼统这个历程,才经由历程继续的体式格局去表达出笼统的构造。

笼统只是剖析和设想的历程当中,一个行动或者说一种技能,经由历程笼统能够获得类。

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

3、派生

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()

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面向对象中的继续的细致内容,更多请关注ki4网别的相干文章!

打赏

感谢您的赞助~

打开支付宝扫一扫,即可进行扫码打赏哦~

版权声明 : 本文未使用任何知识共享协议授权,您可以任何形式自由转载或使用。

 可能感兴趣的文章

评论区

发表评论 / 取消回复

必填

选填

选填

◎欢迎讨论,请在这里发表您的看法及观点。