关于继承
抽象与继承
覆盖、派生
组合
子类调用父类的方法
关于继承
继承我们可以把它看成一种关系,用来描述两个对象之间的关系,在程序中,继承也就是类与类之间的关系,继承也就是用来创建一种新类,新建的类可以继承一个父类也可以继承多个父类。
python中继承的特点:
1.子类可以遗传/重用父类的属性
2.python中一个子类可以同时继承多个父类
3.在继承的背景下,python的类分为两种,新式类和经典类
新式类:但凡继承了object的类Foo,以及该类的子类...都是新式类。在python3中一个类即便是没有显式地继承任何类,默认就会继承object,即python3中所有的类都是新式类。
经典类:没有继承object的类,以及该类的子类...都是经典类。在python2中才区分新式类与经典类,在python2中一个类如果没有显式地继承任何类,也不会继承object。
使用继承的好处:可以减少类与类之间代码冗余。
#单继承与多继承的语法 class ParentClass1: #定义父类 pass class ParentClass2: #定义父类 pass class SubClass1(ParentClass1): #单继承,基类是ParentClass1,派生类是SubClass pass class SubClass2(ParentClass1,ParentClass2): #python支持多继承,用逗号分隔开多个继承的类 pass
#查看继承 __bases__是查看所有继承的父类 class A: pass class B: pass class C(A): pass class D(A,B): pass print(C.__bases__) # (<class '__main__.A'>,) print(D.__bases__) # (<class '__main__.A'>, <class '__main__.B'>)
抽象与继承
继承描述的子类和父类的之间的关系,是一种什么是什么的关系。要找出这种关系,必须先抽象再继承。
抽象即抽取类似或者说比较像的部分,把抽取的相似部分形成一个新的类。
抽象的过程:
1.将麦兜和猪坚强这俩对象比较像的部分抽取成类;
2.将人,猪,狗这三个类比较像的部分抽取成父类。
抽象最主要的作用是划分类别(可以隔离关注点,降低复杂度)
继承是基于抽象的结果,通过编程语言去实现它,肯定是先经历抽象这个过程,才能通过继承的方式去表达出抽象的结构。抽象只是分析和设计的过程中,一个动作或者说一种技巧,通过抽象可以得到类。
覆盖、派生
覆盖
#当子类出现了与父类的名称完全一致的属性或是方法时,会优先使用子类中的 class Person: def say_hi(self): print("hello") class Student(Person): def say_hi(self): print("hello world!") stu = Student() stu.say_hi() # hello world!
派生
#当一个子类中出现了与父类中不同的内容时,这个子类就称之为派生类,通常子类都会写一些新的代码,不可能和父类完全一样 , 既通常都是派生类,所以派生类指的就是子类。 class Animal: ''' 人和狗都是动物,所以创造一个Animal基类 ''' def __init__(self, name, aggressivity, life_value): self.name = name # 人和狗都有自己的昵称; self.aggressivity = aggressivity # 人和狗都有自己的攻击力; self.life_value = life_value # 人和狗都有自己的生命值; def eat(self): print('%s is eating'%self.name) class Dog(Animal): ''' 狗类,继承Animal类 ''' def bite(self, people): ''' 派生:狗有咬人的技能 :param people: ''' people.life_value -= self.aggressivity class Person(Animal): ''' 人类,继承Animal ''' def attack(self, dog): ''' 派生:人有攻击的技能 :param dog: ''' dog.life_value -= self.aggressivity
组合
组合也是一种关系,将一个对象作为另一个对象的属性。组合的作用也是为了重用现有的代码。
class Phone: # 定义一个电话的类 def __init__(self,price,kind,color): self.price = price self.kind = kind self.color = color def call(self): print("正在呼叫XXXX;") def send_message(self): print("正在发送短信....") class Student: # 定义一个学生的类 def __init__(self,name,gender,phone): # 将电话作为学生的一个属性 self.name = name self.gender = gender self.phone = phone def show_info(self): print("name:%s gender:%s" % (self.name,self.gender)) phone = Phone(1000,"apple","red") # 产生一个电话对象 stu1 = Student("rose","male",phone) # 产生一个学生的对象,并将电话对象作为它的属性输入 stu1.phone.call() # 通过学生对象调用电话的功能
子类调用父类的方法
方法一:指名道姓,即父类名.父类方法()
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): Vehicle.__init__(self,name,speed,load,power) self.line=line def run(self): print('地铁%s号线欢迎您' %self.line) Vehicle.run(self) # 通过类名调用父类方法 line13=Subway('中国地铁','180m/s','1000人/箱','电',13) line13.run()
方法二:super()
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()