zoukankan      html  css  js  c++  java
  • OOP >>> 继承

    继承:

    • 继承是一种关系,通过继承关系,一个类可以直接使用另一个类中已定义的方法和属性
    • 被继承的称之为父类或基类,继承父类的类称之为子类
    • 使用继承可以减少代码重复

    # 在python3中创建类时必然继承另一个类,如果没有显示的指定父类,则默认继承object类;object是根类 所有类都直接或间接的继承object

    使用方法:

    在类名后面的括号中指定要继承的父类名称  ​class 类名(父类名):    如:

    class Teacher:
        def __init__(self,name,gender,age):
            self.name = name
            self.gender = gender
            self.age = age
        def say_hi(self):
            print("hi my name is %s age is %s gender is %s" % (self.name,self.age,self.gender))
            
    class Student:
        def __init__(self,name,gender,age):
            self.name = name
            self.gender = gender
            self.age = age
        def say_hi(self):
            print("hi my name is %s age is %s gender is %s" % (self.name,self.age,self.gender))
    #创建两个对象
    t1 = Teacher("Jack","man",20)
    t1.say_hi()
    s1 = Student("Maria","woman",20)
    s1.say_hi()
    
    
    #  此时两处代码基本相同,我们就可以使用继承来重用代码,如下:
    
    
    class Teacher:
        def __init__(self,name,gender,age):
            self.name = name
            self.gender = gender
            self.age = age
        def say_hi(self):
            print("hi my name is %s age is %s gender is %s" % (self.name,self.age,self.gender))
    
    class Student(Teacher):  #指定Teacher类继承Student类
        pass
    
    #创建两个对象
    t1 = Teacher("Jack","man",20)
    t1.say_hi()
    s1 = Student("Maria","woman",20)
    s1.say_hi()

    抽象:

      以上面的例子为例:将 Teacher Student 中完全相同的部分抽取出来,放到另一个类中,并让 Teacher 与 Student 去继承它,这个类称之为 公共父类 ,但是这个类与实际的业务需求是无关的,在现实中也不实际存在,它的作用仅仅是 存储相同代码以减少重复;这一过程我们称之为抽象

      所以上面的例子就可以进行修整:

    # 抽取老师和学生的相同内容 形成一个新的类,作为它们的公共父类
    class Person:
        def __init__(self,name,gender,age):
            self.name = name
            self.gender = gender
            self.age = age
        def say_hi(self):
            print("hi my name is %s age is %s gender is %s" % (self.name,self.age,self.gender))
    class Teacher(Person):    #指定Teacher类继承Person类
        pass
    class Student(Person):  #指定Student类继承Person类
        pass
    
    #创建两个对象
    t1 = Teacher("Jack","man",20)
    t1.say_hi()
    s1 = Student("Maria","woman",20)
    s1.say_hi()

    所以正确思路是:先抽象再继承

    属性查找顺序:

      对象本身的名称空间 >>> 类的名称空间 >>> 父类的名称空间 >>> 父类的父类名称空间 >>> ...... >>> object类

      会沿着继承关系一直往后查找,直到找到为止,由于object是所有类的根类,所以如果找不着最后都会查找object类!

    派生与覆盖:

      派生:

        当父类提供的属性无法完全满足子类的需求时,子类可以增加自己的属性或方法,或者覆盖父类已经存在的属性,此时子类称之为父类的派生类

        通常子类都会写一些新的代码,不可能和父类完全一样 , 既通常都是派生类

      覆盖:overrides

        在子类中如果出现于父类相同的属性名称,根据查找顺序,优先使用子类中的属性,这种行为也称为覆盖

    子类中使用父类方法:

      很多情况下,子类中的代码与父类中仅有小部分不同,却不得不在子类定义新的方法,这时候可以在子类中调用父类已有的方法,来完成大部分工作,子类仅需编写一小部分与父类不同的代码即可

      方法一:使用类名直接调用,该方式与继承没有关系,即使没有继承关系,也可以调用   如:类名称.你要调的父类的属性或方法(self) 

      方法二使用super( 类名, self ).方法        >>>   常用方法     如:      # 括号内可不写

    class Vehicle: #定义交通工具类
         Country='China'
         def __init__(self,name,speed,load,power):
             self.name=name
             self.speed=speed
             self.load=load
             self.power=power
    
         def run(self):
             print('开动啦...')
    
    class Subway(Vehicle): #地铁
        def __init__(self,name,speed,load,power,line):
            #super(Subway,self) 就相当于实例本身 在python3中super()等同于super(Subway,self)
            super().__init__(name,speed,load,power)
            self.line=line
    
        def run(self):
            print('地铁%s号线欢迎您' %self.line)
            super(Subway,self).run()
    
    class Mobike(Vehicle):#摩拜单车
        pass
    
    line13=Subway('中国地铁','180m/s','1000人/箱','',13)
    line13.run()

     ******当你继承一个现有的类,并且你覆盖了父类的init方法时,必须在初始化方法的第一行调用父类的初始化方法,并传入父类所需的参数

    新式类与经典类:

      新式类:任何显式或隐式地继承自object的类就称之为新式类,python3中任何类都是直接或间接继承了Object ,所以 python3中全都是新式类 

        经典类:不是Object的子类,仅在python2中出现

        新式类是广度继承;经典类是深度继承;

      如果出现了菱形继承,那么新式类就会先深度,后广度

    组合:

      软件重用的重要方式除了继承之外还有另外一种方式,即:组合

      组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合

      如:

    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() #可以使用组合的类产生的对象所持有的方法

    ###################################

    什么时候用继承?

      通过继承建立了派生类与基类之间的关系,它是一种'是'的关系,比如白马是马,人是动物。

      当类之间有很多相同的功能,提取这些共同的功能做成基类,用继承比较好,比如老师是人,学生是人

    什么时候用组合?

      用组合的方式建立了类与组合的类之间的关系,它是一种‘有’的关系,比如教授有生日,教授教python和linux课程,教授有学生s1、s2、s3...

        

  • 相关阅读:
    20190211 模拟训练 A. 大猫咪
    如何诊断节点重启问题
    诊断 Grid Infrastructure 启动问题 (文档 ID 1623340.1)
    bzoj4025 二分图
    root.sh脚本支持checkpoints文件实现重复运行
    [IOI2018] seats 排座位
    最常见的 5 个导致节点重新启动、驱逐或 CRS 意外重启的问题 (文档 ID 1524455.1)
    [IOI2018] werewolf 狼人
    OCR/Vote disk 维护操作: (添加/删除/替换/移动) (文档 ID 1674859.1)
    [POI2011]ROT-Tree Rotations
  • 原文地址:https://www.cnblogs.com/pupy/p/11247104.html
Copyright © 2011-2022 走看看