zoukankan      html  css  js  c++  java
  • 面向编程(二)继承

    一.基础

     1 class Garen:
     2     camp='Demacia'
     3     n=0
     4     hobby=[]        #类的变量一般定义成不可变的
     5     def __init__(self,nickname,aggressivity=58,life_value=455):
     6         self.nickname=nickname           #为自己的盖伦起了个别名
     7         self.aggressivity=aggressivity
     8         self.life_value=life_value
     9         Garen.n+=1                #类.n  对象每产生一个名字(统计实例化次数)
    10         #self.hobby=[]
    11     def attack(self,enemy):
    12         enemy.life_value-=self.aggressivity
    13 
    14 g1=Garen('草丛伦')
    15 g2=Garen('草丛伦2')
    16 g3=Garen('草丛伦3')
    17 print(g1.hobby,id(g1.hobby))
    18 print(g2.hobby,id(g2.hobby))
    19 print(g3.hobby,id(g3.hobby))
    20 print(g1.n)          #
    21 print(g3.n)
    22 
    23 
    24 
    25 
    26 
    27 [] 13837768               #指向同一个列表,同一个内存地址
    28 [] 13837768
    29 [] 13837768
    30 3
    31 3
     1 g1.hobby.append('g1 hobby')
     2 g2.hobby.append('g2 hobby')
     3 g3.hobby.append('g3 hobby')
     4 print(g1.hobby)
     5 g1.camp='12123'
     6 print(g1.camp)
     7 
     8 
     9 
    10 ['g1 hobby', 'g2 hobby', 'g3 hobby']    #可变类型
    11 12123                     #不可变类型
     1 class Garen:
     2     camp='Demacia'
     3     n=0
     4     #hobby=[]        #类的变量一般定义成不可变的
     5     def __init__(self,nickname,aggressivity=58,life_value=455):
     6         self.nickname=nickname           #为自己的盖伦起了个别名
     7         self.aggressivity=aggressivity
     8         self.life_value=life_value
     9         Garen.n+=1                #类.n  对象每产生一个名字(统计实例化次数)
    10         self.hobby=[]       #定义在自己里面,别的实例进不来
    11     def attack(self,enemy):
    12         enemy.life_value-=self.aggressivity
    13 g1=Garen('草丛伦')
    14 g2=Garen('草丛伦2')
    15 g3=Garen('草丛伦3')
    16 
    17 
    18 g1.hobby.append('g1 hobby')
    19 g2.hobby.append('g2 hobby')
    20 g3.hobby.append('g3 hobby')
    21 print(g1.hobby)
    22 
    23 
    24 
    25 
    26 
    27 ['g1 hobby']
     1 class Garen:
     2     camp='Demacia'
     3     n=0
     4     #hobby=[]        #类的变量一般定义成不可变的
     5     def __init__(self,nickname,aggressivity=58,life_value=455):
     6         self.nickname=nickname           #为自己的盖伦起了个别名
     7         self.aggressivity=aggressivity
     8         self.life_value=life_value
     9         Garen.n+=1                #类.n  对象每产生一个名字(统计实例化次数)
    10         self.hobby=[]       #定义在自己里面,别的实例进不来
    11     def attack(self,enemy):
    12         print('=====>')
    13         enemy.life_value-=self.aggressivity
    14 
    15 g1=Garen('草丛伦')
    16 g2=Garen('草丛伦2')
    17 # print(g1.hobby,id(g1.hobby))
    18 # print(g2.hobby,id(g2.hobby))
    19 # print(g3.hobby,id(g3.hobby))
    20 # print(g1.n)          #
    21 # print(g3.n)
    22 print(g1.attack)
    23 print(Garen.attack)
    24 g1.attack(g2)            #绑定方法指向函数的功能,就是绑定到每个对象身上的
    25                         #对象调绑定方法操作的就是对象自己,Garen.attack(g1,g2) g2为位置参数
    26 #其实就相当于Gaven.attack(g1,g2)
    27 #区别:可以把对象自己当成参数传进去

    二.继承

    1.什么是继承

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

      分为: 单继承和多继承

     1 class ParentClass1:    #定义父类
     2     pass
     3 class ParentClass2:    #定义父类
     4     pass
     5 class SubClass1(ParentClass1): #单继承,基类是ParentClass1,派生类是SubClass
     6     pass
     7 class SubClass2(ParentClass1,ParentClass2):  #多继承,用逗号分隔开多个继承的类
     8     pass
    
    73 
    74 print(SubClass1.__bases__)
    75 print(SubClass2.__bases__)
    76 print(ParentClass1.__bases__)           #python的类默认继承object类,object是所有python类的基类,它提供一些常见方法如(_str_)实现
    77 
    78 
    79 
    80 (<class '__main__.ParentClass1'>,)
    81 (<class '__main__.ParentClass1'>, <class '__main__.ParentClass2'>)
    82 (<class 'object'>,)

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

    抽象分成两个层次: 

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

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

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

     

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

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

     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 
     7     def move_forward(self):
     8         print('%s move forward' %self.nickname)
     9 
    10     def move_backward(self):
    11         print('%s move backward' %self.nickname)
    12 
    13     def move_left(self):
    14         print('%s move forward' %self.nickname)
    15 
    16     def move_right(self):
    17         print('%s move forward' %self.nickname)
    18 
    19     def attack(self,enemy):
    20         enemy.life_value-=self.aggressivity
    21 class Garen(Hero):
    22     pass
    23 
    24 class Riven(Hero):
    25     pass
    26 
    27 g1=Garen('草丛伦',100,300)
    28 r1=Riven('锐雯雯',57,200)
    29 
    30 print(g1.life_value)
    31 r1.attack(g1)
    32 print(g1.life_value)
    33 
    34 '''
    35 运行结果
    36 300
    37 243
    38 '''

    2.派生

    如果在子类中定义与父类相同的,走子类中的。也可以定义一个新的。
     1 class Hero:
     2     def __init__(self,nickname,
     3                  aggressivity,
     4                  life_value):
     5         self.nickname = nickname
     6         self.aggressivity = aggressivity
     7         self.life_value = life_value
     8 
     9     def attack(self,enemy):
    10         enemy.life_value -= self.aggressivity
    11 
    12 
    13 class Garen(Hero):
    14     camp='Demacia'
    15     def attack(self,enemy):
    16         print('from garen attack')        #如果在子类中定义与父类相同的,走子类中的
    17     def fire(self):
    18         print('%s is fireing' %self.nickname)
    19 
    20 class Riven(Hero):
    21     camp='Noxus'
    22 
    23 g1=Garen('garen',18,200)
    24 r1=Riven('rivren',18,200)
    25 g1.attack(r1)
    26 print(g1.camp)
    27 print(r1.camp)

     1.重用

     1 class Hero:
     2     def __init__(self,nickname,
     3                  aggressivity,
     4                  life_value):
     5         self.nickname = nickname
     6         self.aggressivity = aggressivity
     7         self.life_value = life_value
     8 
     9     def attack(self,enemy):   5.
    10         print('Hero attack')
    11         enemy.life_value -= self.aggressivity
    12 class Garen(Hero):
    13     camp='Demacia'
    14     def attack(self,enemy):     # 3.指向类的函数 self=g1,enemy=r1
    15         Hero.attack(self,enemy)     #重用父类的 4
    16         print('from garen attack')        #如果在子类中定义与父类相同的,走子类中的
    17     def fire(self):
    18         print('%s is fireing' %self.nickname)
    19 
    20 class Riven(Hero):
    21     camp='Noxus'
    22 
    23 g1=Garen('garen',18,200)  #  1.g1的名称空间
    24 r1=Riven('rivren',18,200)
    25 g1.attack(r1)      # 2.g1的绑定方法  不用传参数,实际传的g1和r1
    26 
    27 
    28 Hero attack
    29 from garen attack
     1 class Hero:
     2     def __init__(self,nickname,
     3                  aggressivity,
     4                  life_value):
     5         self.nickname = nickname
     6         self.aggressivity = aggressivity
     7         self.life_value = life_value
     8 
     9     def attack(self,enemy):
    10         print('Hero attack')
    11         enemy.life_value -= self.aggressivity
    12 class Garen(Hero):
    13     camp='Demacia'
    14     def __init__(self,nickname,aggressivity,life_value,script):       ##
    15         Hero.__init__(self,nickname,aggressivity,life_value)  ##调用父类功能
    16         self.script = script   #新属性
    17     def attack(self,enemy):  #self=g1,enemy=r1 #在这里定义新的attack,不再使用父类的attack,且不会影响父类
    18         Hero.attack(self,enemy)     #重用父类的
    19         print('from garen attack')        #如果在子类中定义与父类相同的,走子类中的
    20     def fire(self):
    21         print('%s is fireing' %self.nickname)
    22 
    23 class Riven(Hero):
    24     camp='Noxus'
    25 
    26 g1=Garen('garen',18,200,'人在塔下') #Garen.__init__(g1,'garen',18,200,'人在塔下')

    2.组合

     1 class Teacher:
     2     def __init__(self,name,sex,course):
     3         self.name=name
     4         self.sex=sex
     5         self.course=course
     6 
     7 class Student:
     8     def __init__(self,name,sex,course):
     9         self.name=name
    10         self.sex=sex
    11         self.course=course
    12 
    13 class Course:
    14     def __init__(self,name,price,period):
    15         self.name=name
    16         self.price=price
    17         self.period=period
    18 
    19 python_obj=Course('python',15800,'7m')
    20 t1=Teacher('egon','male',python_obj)
    21 s1=Student('cobila','male',python_obj)
      print(s1.course.name)
      print(t1.course.name)

    继承: 类与类之间是的关系,完成代码重用   (人和狗都是动物)

    组合:类与类之间有的关系,(老师,学生与生日    老师,学生与课程  学生与分数)

    3.接口与归一化设计

    继承

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

    二:声明某个子类兼容于某基类,定义一个接口类Interface,接口类定义了一些接口名(就是函数名)

    继承的第二种含义非常重要,它又叫接口继承。接口继承实质上是要求做一个良好的抽象,这个抽象规定了一个兼容接口,使得外部调用者无需关心具体细节,可一视同仁的处理时限了特定接口的所有对象——这在程序设计上,叫做归一化。

    1.主动抛出异常

    class Animal:
        def run(self):
            raise AttributeError('子类必须实现这个方法')
        def speak(self):
            raise AttributeError('子类必须实现这个方法')
    
    class People(Animal):
        pass
        # def run(self):
        #     print('人正在走')
        # def speak(self):
        #     print('说话')
    
    peo1=People()
    peo1.run()
    
    
    
    
    
       raise AttributeError('子类必须实现这个方法')
    AttributeError: 子类必须实现这个方法
    

      

    2.抽象类

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

    普通类除了raise抛出异常没有其他方法限制子类必须实现

     1 import abc
     2 class Animal(metaclass=abc.ABCMeta):
     3     @abc.abstractmethod          #必须被子类实现run
     4     def run(self):
     5         pass
     6     @abc.abstractmethod          #必须被子类实现speak
     7     def speak(self):
     8         pass
     9 
    10 
    11 class People(Animal):
    12     def run(self):
    13         pass
    14 
    15     def speak(self):
    16         pass
    17 peo1=People()                   #做实例化时会报错
  • 相关阅读:
    [纯C#实现]基于BP神经网络的中文手写识别算法
    【转载】Jedis对管道、事务以及Watch的操作详细解析
    redis 缓存用户账单策略
    redis 通配符 批量删除key
    explain分析sql效率
    mysql 常用命令大全
    【转载】实战mysql分区(PARTITION)
    mysql表名忽略大小写配置
    【转】微服务架构的分布式事务解决方案
    【转载】Mysql中的Btree与Hash索引比较
  • 原文地址:https://www.cnblogs.com/jiangshitong/p/6734119.html
Copyright © 2011-2022 走看看