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()                   #做实例化时会报错
  • 相关阅读:
    阿里云 k8s 部署 Spring Cloud Alibaba 微服务实践 (四) 自动化部署
    阿里云 k8s 部署 Spring Cloud Alibaba 微服务实践 (三) 服务观测
    阿里云 k8s 部署 Spring Cloud Alibaba 微服务实践 (二) 部署微服务程序
    阿里云 k8s 部署 Spring Cloud Alibaba 微服务实践 (一) 部署 Nacos
    C++知识点
    libmkl 学习笔记
    基于tesseract-OCR进行中文识别
    poco编译与运行
    Linux下的I/O复用与epoll详解(转载)
    高并发网络编程之epoll详解(转载)
  • 原文地址:https://www.cnblogs.com/jiangshitong/p/6734119.html
Copyright © 2011-2022 走看看