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