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...

    

猜你喜欢

转载自www.cnblogs.com/pupy/p/11247104.html
OOP