面向对象之继承
一.概念
如果有两个或两个以上的类具有相同的属性和方法,我们可以抽取出来,把抽取出来的部分作为各个类的公共部分,我们称抽取出的这部分为基类[Base Class]或者父类[Father Class]、超类[Super Class].
举例:[我直接以多继承举例]
第一种情况,父类中没有构造函数
1 class Father(object): 2 def eat(self): 3 print('father is eating') 4 5 6 class Mother(object): 7 def play(self): 8 print('mother is playing') 9 10 11 class Children(Father, Mother): 12 pass 13 14 15 c = Children() 16 c.eat() 17 c.play()
运行结果
1 father is eating 2 mother is playing
第二种情况,父类中有构造函数
1 class Father(object): 2 def __init__(self, money): # 构造函数 3 self.money = money # 实例属性 4 5 def get(self): 6 print(f'father had got {self.money}$') 7 8 9 class Mother(object): 10 def __init__(self, clothes): # 构造函数 11 self.clothes = clothes # 实例属性 12 13 def shop(self): 14 print(f'mother has go shopping to buy {self.clothes}') 15 16 17 # 如果子类想要用父类中的实例属性,则需要继承父类的构造函数才能使用,否则会报错 18 # 如果父类中含有多个重名的函数,那么子类只会调用父类列表第一个重名的函数 19 class Children(Father, Mother): 20 def __init__(self, money, clothes): 21 Father.__init__(self, money) 22 Mother.__init__(self, clothes) 23 24 25 c = Children(100,'李宁') 26 c.get() 27 c.shop()
运行结果
1 father had got 100$ 2 mother has go shopping to buy 李宁
第三种情况,父类中有构造函数,子类中没有
1 class Father(object): 2 def __init__(self, money): # 构造函数 3 self.money = money # 实例属性 4 5 def get(self): 6 print(f'father had got {self.money}$') 7 8 9 class Mother(object): 10 def __init__(self, clothes): # 构造函数 11 self.clothes = clothes # 实例属性 12 13 def shop(self): 14 print(f'mother has go shopping to buy {self.clothes}') 15 16 17 class Children(Father, Mother): 18 19 pass 20 21 22 c = Children(100) 23 c.get() 24 c.shop()
运行结果则是 只能调用Father中的函数,而Mother中的无法调用
总结:
1.在多继承中,如果父类中有构造函数,子类没有,而子类需要使用父类中的实例属性或函数,那么子类只会调用第一个父类的函数;如果想要子类使用所有父类的实例属性或函数,那么同样需要继承父类中的构造函数,但是如果使用super()都只能调用父类列表中第一个父类中的构造函数,所以只能使用上述例子的第二种继承方法
2.如果在父类中都没有构造函数,那么子类可以直接调用
二、函数的重写[重点掌握]
函数的重写[override],使用的前提是在继承的情况下;
如果在子类中重新实现了父类中的函数,那么这个过程叫做函数的重写。
举例:
1 # 1.第一种情况:普通函数的重写 2 class Animals(object): 3 def walk(self): 4 print('正在跑') 5 6 7 class Dog(Animals): 8 pass 9 10 11 class Cat(Animals): 12 pass 13 14 15 class Bird(Animals): 16 def walk(self): 17 print('鸟只会飞') 18 19 20 animal = Bird() 21 animal.walk() 22 23 animal2 = Dog() 24 animal2.walk() 25 26 # 2.第二种情况,系统函数的重写,拿object举例,因为所有类的基类都是object 27 class Person(object): 28 def __init__(self, name, age): 29 self.name = name 30 self.age = age 31 32 def __str__(self): 33 return f'姓名:{self.name},年龄:{self.age}' 34 35 def __repr__(self): 36 return f'姓名:{self.name},年龄:{self.age}' 37 38 __repr__ == __str__ 39 40 41 p = Person('小刚',19) 42 print(p)
运行结果:
1 鸟只会飞 2 正在跑 3 姓名:小刚,年龄:19
总结:
1.什么时候用函数的重写
如果一个父类中有多个子类,父类中的函数能够满足大部分子类的使用,只有少部分函数无法使用时,我们可以用函数的重写;
2.什么时候需要重写__str__
如果希望打印出的信息是当前对象的属性,那么需要在子类中重写__str__,因为它返回的是一个字符串,所以建议将字符串格式化之后返回,如例子中的。
3.什么时候需要重写__repr__
如果打印出的信息对象元素是存在于列表等可迭代对象中,它会直接返回可迭代对象,也就是返回默认的地址形式,但是我们需要的是列表中的属性信息,那么我们就需要重写__repr__
4.只要有系统函数的重写都需要加上 __repr__ == __str__
三、函数的重写和函数的重载有什么区别
【面试题】简述函数重写和函数重载的区别
函数重写:override,在继承的前提下,如果子类中重新实现了父类中的函数
函数重载[运算符重载]:overload,对于自定义的类,通过该类创建的对象,如果不支持某些运算,如:+ - * / > < >= <= == !=等,则可以在该类中实现这些运算符对应的函数
1 class Person(object): 2 def __init__(self, age): 3 self.age = age 4 5 def __add__(self, other): # 函数重载 6 # self和other表示参与运算的两个对象 7 # 结合实际情况,两个对象无法相加,可以对两个对象的属性进行加法运算 8 return Person(self.age+other.age) 9 10 def __str__(self): 11 return str(self.age) 12 __repr__ == __str__ 13 14 15 p1 = Person(10) 16 p2 = Person(5) 17 18 print(p1+p2) 19 print(p1.__add__(p2))
标签:__,复习,继承,self,面向对象,父类,class,def,函数 From: https://www.cnblogs.com/liujinjing521/p/17086991.html