• Python之面向对象继承和派生


    Python之面向对象继承和派生

      什么是继承:

        继承是一种创建新的类的方法。在Python中,新建的类可以继承自一个或多个父类。原始类称为基类或超类。

        新建的类称为派生类或子类。

       Python中类的继承分为单继承和多继承。

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

    print(SubClass1.__bases__) #查看继承的类。

      注意:

        如果没有指定基类。Python的类会默认继承object类。object是所有Python类的基类。他提供了一些常见方法。屁如:(__str__) 的实现。

      继承与抽象(先抽象再继承):

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

        抽象分为两个层次:

        1,将Obama和George这两个对象比较像的部分抽取成类。

        2,将人,猴,狗这三个类比较像的部分抽取成父类。

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

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

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

      多态:同一种事物的不同形态。人,狗都是动物。

      继承与重用性:

        重用性:将重复的功能写在父类里。在子类里继承即可。

      1 ==========================第一部分
      2 例如
      3 
      4   猫可以:喵喵叫、吃、喝、拉、撒
      5 
      6   狗可以:汪汪叫、吃、喝、拉、撒
      7 
      8 如果我们要分别为猫和狗创建一个类,那么就需要为 猫 和 狗 实现他们所有的功能,伪代码如下:
      9  
     10 
     11 #猫和狗有大量相同的内容
     12 class 猫:
     13 
     14     def 喵喵叫(self):
     15         print '喵喵叫'
     16 
     17     def 吃(self):
     18         # do something
     19 
     20     def 喝(self):
     21         # do something
     22 
     23     def 拉(self):
     24         # do something
     25 
     26     def 撒(self):
     27         # do something
     28 
     29 class 狗:
     30 
     31     def 汪汪叫(self):
     32         print '喵喵叫'
     33 
     34     def 吃(self):
     35         # do something
     36 
     37     def 喝(self):
     38         # do something
     39 
     40     def 拉(self):
     41         # do something
     42 
     43     def 撒(self):
     44         # do something
     45 
     46 
     47 
     48 ==========================第二部分
     49 上述代码不难看出,吃、喝、拉、撒是猫和狗都具有的功能,而我们却分别的猫和狗的类中编写了两次。如果使用 继承 的思想,如下实现:
     50 
     51   动物:吃、喝、拉、撒
     52 
     53      猫:喵喵叫(猫继承动物的功能)
     54 
     55      狗:汪汪叫(狗继承动物的功能)
     56 
     57 伪代码如下:
     58 class 动物:
     59 
     60     def 吃(self):
     61         # do something
     62 
     63     def 喝(self):
     64         # do something
     65 
     66     def 拉(self):
     67         # do something
     68 
     69     def 撒(self):
     70         # do something
     71 
     72 # 在类后面括号中写入另外一个类名,表示当前类继承另外一个类
     73 class 猫(动物):
     74 
     75     def 喵喵叫(self):
     76         print '喵喵叫'
     77         
     78 # 在类后面括号中写入另外一个类名,表示当前类继承另外一个类
     79 class 狗(动物):
     80 
     81     def 汪汪叫(self):
     82         print '喵喵叫'
     83 
     84 
     85 
     86 
     87 ==========================第三部分
     88 #继承的代码实现
     89 class Animal:
     90 
     91     def eat(self):
     92         print("%s 吃 " %self.name)
     93 
     94     def drink(self):
     95         print ("%s 喝 " %self.name)
     96 
     97     def shit(self):
     98         print ("%s 拉 " %self.name)
     99 
    100     def pee(self):
    101         print ("%s 撒 " %self.name)
    102 
    103 
    104 class Cat(Animal):
    105 
    106     def __init__(self, name):
    107         self.name = name
    108         self.breed = ''
    109 
    110     def cry(self):
    111         print('喵喵叫')
    112 
    113 class Dog(Animal):
    114 
    115     def __init__(self, name):
    116         self.name = name
    117         self.breed=''
    118 
    119     def cry(self):
    120         print('汪汪叫')
    121 
    122 
    123 # ######### 执行 #########
    124 
    125 c1 = Cat('小白家的小黑猫')
    126 c1.eat()
    127 
    128 c2 = Cat('小黑的小白猫')
    129 c2.drink()
    130 
    131 d1 = Dog('胖子家的小瘦狗')
    132 d1.eat()
    133 
    134 使用继承来重用代码比较好的例子

    在开发程序的过程中,如果我们定义了一个类A,然后又想新建立另外一个类B,但是类B的大部分内容与类A的相同时

    我们不可能从头开始写一个类B,这就用到了类的继承的概念。

    通过继承的方式新建类B,让B继承A,B会‘遗传’A的所有属性(数据属性和函数属性),实现代码重用

    class Hero:
        def __init__(self,nickname,aggressivity,life_value):
            self.nickname=nickname
            self.aggressivity=aggressivity
            self.life_value=life_value
    
        def move_forward(self):
            print('%s move forward' %self.nickname)
    
        def move_backward(self):
            print('%s move backward' %self.nickname)
    
        def move_left(self):
            print('%s move forward' %self.nickname)
    
        def move_right(self):
            print('%s move forward' %self.nickname)
    
        def attack(self,enemy):
            enemy.life_value-=self.aggressivity
    class Garen(Hero):
        pass
    
    class Riven(Hero):
        pass
    
    g1=Garen('草丛伦',100,300)
    r1=Riven('锐雯雯',57,200)
    
    print(g1.life_value)
    r1.attack(g1)
    print(g1.life_value)
    
    '''
    运行结果
    '''

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

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

    重点!!!:再看属性查找

    class Foo:
        def f1(self):
            print('Foo.f1')
    
        def f2(self):
            print('Foo.f2')
            self.f1()
    
    class Bar(Foo):
        def f1(self):
            print('Foo.f1')
    
    
    b=Bar()
    b.f2()

      派生:

        首先要继承一个父类,如果自己不定义自己的内容,那就从父类里拿。

        如果在子类里定义和父类重名的东西,那么在调用时,以子类为准。

        当然,也可以自己定义一个新的功能,父类没有的功能。

      

      如何在子类里派生的方法里,重用父类的逻辑:

         如何在子类的方法里调用父类的方法。

    #派生
    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() Hero.attack(self,enemy) #用父类里的attack,参数是Hero里的attack的参数。这里的self是g1,enemy是r1 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()

      在子类里,也定义init,这个init是和父类的init不冲突的。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') enemy.life_value -= self.aggressivity
    # print(Hero.__init__) # print(Hero.attack)

    class Garen(Hero): camp = 'Demacia' def __init__(self, nickname, aggressivity, life_value, script): Hero.__init__(self,nickname,aggressivity,life_value) #调用父类的init方法, # self.nickname = nickname # self.aggressivity = aggressivity # self.life_value = life_value self.script = script #也可以自己加自己的init。
    def attack(self, enemy): # self=g1,enemy=r1 # self.attack(enemy) #g1.attack() Hero.attack(self, enemy) print('from garen attack')
    def fire(self): print('%s is firing' % self.nickname)
    # g1=Garen('garen',18,200) #Garen.__init__(g1,'garen',18,200)
    g1=Garen('garen',18,200,'人在塔在') #Garen.__init__(g1,'garen',18,200) print(g1.script)

      组合:

          多个类组合在一起。 解决代码的重用性。是一种类与类之间与的关系。

    class Teacher:
        def __init__(self,name,sex,course,birth):
            self.name = name
            self.sex = sex
            self.course = course
            self.birth = birth
    
    class Student:
        def __init__(self,name,sex,course):
            self.name = name
            self.sex = sex
            self.course = course
    
    class Course:
        def __init__(self,name,price,peroid):
            self.name = name
            self.price = price
            self.peroid = peroid
    
    
    python_obj=Course('python',15800,'7m')
    t1=Teacher('egon','male',python_obj)
    s1=Student('cobila','male',python_obj)
    
    print(s1.course.name)
    print(t1.course.name)
    
    
    
    class Teacher:
        def __init__(self,name,sex,course_name,course_price,course_period):
            self.name=name
            self.sex=sex
            self.course_name=course_name
            self.course_price=course_price
            self.course_period=course_period
    
    
    class Student:
        def __init__(self,name,sex,course_name,course_price,course_period):
            self.name=name
            self.sex=sex
            self.course_name=course_name
            self.course_price=course_price
            self.course_period=course_period
    
    t1=Teacher('egon','male','python',15800,'7m')
    s1=Student('cobila','male','python',15800,'7m')
    
    print(s1.course.name)
    print(t1.course.name)

      接口与归一化设计:

        接口:接口是对外入口,Python是没有接口的概念的。所以Python只能用继承去模拟Java的接口。

    class Animal:
        def run(self):
            #主动抛异常
            raise AttributeError('子类必须实现这个方法')
    
        def speak(self):
            raise AttributeError('子类必须实现这个方法')
    
    class People(Animal):
        def run(self):
            print("Human is walk")
    
        def speak(self):
            print("man is tell")
    
    class Pig(Animal):
        def run(self):
            print('Pig is walking')
    
        def speak(self):
            print('Pig wow')
    
    
    peo1=People()
    # peo1.run()
    peo1.speak()
    
    # peo1=People()
    # pig1=Pig()
    #
    # peo1.run()
    # pig1.run()
    
    
    
    
    # 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('进程数据的读取方法')
    
    
    
    # t1=Txt()
    # s1=Sata()
    # p1=Process()
    
    
    
    # t1.read()
    # t1.write()
    
    # s1.read()
    # s1.write()
    
    # p1.read()
    # p1.write()

      

    主动抛异常:

    class Animal:
        def run(self):
            #主动抛异常
            raise AttributeError('子类必须实现这个方法')
    
        def speak(self):
            raise AttributeError('子类必须实现这个方法')

    抽象类:

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

      用abc模块。

        所有子类,必须实现父类中加了装饰器函数的方法。否则无法实例。

    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)

        

  • 相关阅读:
    20200304(10)
    20200303Tuesday(9)
    词根词缀explicit(8)
    词根词缀(7)
    20200303(6)
    什么是ring0-ring3
    20200301a
    mark字体大全
    评估评价 提高专项(5)
    图的广度优先遍历算法
  • 原文地址:https://www.cnblogs.com/george92/p/9161788.html
Copyright © 2020-2023  润新知