#在Python的多继承中,如果子类继承的多个父类中包含了同名的方法,子类在调用时会选择哪个
class Item :
def info (self):
print("Item中的方法","这是一个商品")
class Product:
def info(self):
print("Product中的方法" , "这是一个工业产品")
class Mouse(Item, Product):
pass
m = Mouse()
m.info()
输出:
Item中的方法,这是一个商品
class Item :
def info (self):
print("Item中的方法","这是一个商品")
class Product:
def info(self):
print("Product中的方法" , "这是一个工业产品")
class Mouse(Product, Item):
pass
m = Mouse()
m.info()
输出:
Product中的方法 这是一个工业产品
总结:
可见多继承中,父类有同名方法,子类在调用时会选择继承中排在前面的父类方法
拓展:
如果子类也包含同名方法,子类调用同名方法,优先选择自己的方法,这叫做重写,也叫覆盖override
class Item :
def info (self):
print("Item中的方法","这是一个商品")
class Product:
def info(self):
print("Product中的方法" , "这是一个工业产品")
class Mouse(Item, Product):
def info(self):
print("这是一个鼠标")
m = Mouse()
m.info()
输出:
这是一个鼠标
拓展1:
如果在多继承中子类和父类方法同名了,父类方法被子类方法覆盖了,但是我仍然想要调用父类的方法,那该怎么办?
Python 类相当于类空间,因此Python 类中的方法本质上相当于类空间内的函数。
所以,即使是实例方法, Python 也允许通过类名调用。区别在于: 在通过类名调用实例方法时,Python 不会为实例方法的第一个参数self 自动绑定参数值,而是需要程序显式绑定第一个参数self。这种机制被称为未绑定方法。
再看代码:
# 在Python的多继承中,如果子类继承的多个父类中包含了同名的方法,子类在调用时会选择哪个
class Item :
def info (self):
print("Item中的方法","这是一个商品")
class Product:
def info(self):
print("Product中的方法" , "这是一个工业产品")
class Mouse(Item, Product):
def info(self):
print("这是一个鼠标")
def all_method(self):
self.info() #子类的info方法
Item.info(self) #Item父类的info方法
Product.info(self) #Product父类的info方法
m = Mouse()
m.all_method()
输出结果:
这是一个鼠标
Item中的方法 这是一个商品
Product中的方法 这是一个工业产品
这说明通过这种方法所有的info方法都被调用了
拓展2:
使用super函数调用父类的构造方法
因为构造方法是Python内置的特殊方法,在类中很常见,所以在多继承中必须考虑子类怎么调用父类的构造方法:
class Employee:
def __init__(self, salary):
self.salary = salary
def work(self):
print("普通员工正在写代码,工资是:", self.salary)
class Customer:
def __init__(self, favorite, address):
self.favorite = favorite
self.address = address
def info(self):
print("我是一个顾客,我的爱好是%s, 地址是%s" %(self.favorite, self.address))
class Manger(Employee, Customer):
pass
m = Manger(5000) #子类继承的是父类Employee的构造方法
m.work() #
m.info() #出错,因为info中使用了Customer中定义的构造属性,但是子类并没有从Customer中继承favorite, address属性
所以构造方法很特殊,因为他为对象初始化了属性,这些属性在其他方法中被使用,如果在子类继承中不继承父类的init方法,那么复用父类的一些方法,就会出现错误,继承的最大有点就是复用,如果不能复用,那么继承毫无意义,所以我们必须在子类中重写父类的构造方法,继承所有父类的init方法,同时也可以扩展子类的属性。继承父类的init方法有两种:
- 使用未绑定方法, 这种方式很容易理解。因为构造方法也是实例方法, 当然可以通过这种方式来调用。
- 使用super()函数调用父类的构造方法。
class Employee:
def __init__(self, salary):
self.salary = salary
def work(self):
print("普通员工正在写代码,工资是:", self.salary)
class Customer:
def __init__(self, favorite, address):
self.favorite = favorite
self.address = address
def info(self):
print("我是一个顾客,我的爱好是%s, 地址是%s" %(self.favorite, self.address))
# class Manager(Employee, Customer):
# pass
#
# m = Manager(5000) #子类继承的是父类Employee的构造方法
# m.work() #
# m.info() #出错,因为info中使用了Customer中定义的构造属性,但是子类并没有从Customer中继承favorite, address属性
class Manager(Employee, Customer):
def __init__(self, salary, favorite, address, occupation): #重写init,要写所有父类中的init属性,同时可以添加子类的属性occupation
self.occupation = "new add"
print("这是Manager类的构造方法")
# 继承Employee中的init方法,super方法,两种写法都可以
# super().__init__(salary) #super写法1
super(Manager, self).__init__(salary) #super写法2
# 继承Customer方法,通过调用未绑定的方法,显式传递self
Customer.__init__(self, favorite, address)
print("我是子类Manager 初始化方法init中定义的属性:", self.occupation)
m = Manager(5000, 'sing', 'china', 'IT')
m.work()
m.info()
来源:51CTO
作者:wx5a4c600866558
链接:https://blog.51cto.com/13560219/2453833