Python基础——第十三章 子子孙孙无穷尽也之多继承,super函数,类的实例调用,魔法方法

思考题:

上一章讲到了继承,一个类可以继承一个类,继承之后可以使用父类的方法和属性,那一个类可以继承多个类吗?如果可以继承多个类的话,那如果两个父类中有一样的方法的情况下,子类继承哪一个呢?

 上章讲到的继承指的是子类只继承一个基类,但实际应用中有可能需要继承多个类的情况,即多继承。和实际生活联系下就明白了,一个孩子会继承父亲的一些特征,同时也会继承母亲的一些特征,可以从这个角度来理解多继承。

 1、多继承

class Father:              #定义父亲这个基类
    def __init__(self,name,weight):  #定义方法,属性
        self.name = name
        self.weight = weight
        print("遗传父亲的体重")
class Mother:                    #定义母亲基类
    def __init__(self,name,height):
        self.name = name + "'s laopo"
        self.height = height
        print("遗传母亲的身高")

'''继承的顺序是先Mother后Father,即从左到右的顺序,继承了Father的weight属性和Mother的height属性'''
class Daughter(Mother,Father):
    def __init__(self,name,weight,height):
        Father.__init__(self,name,weight)  #父类的调用
        Mother.__init__(self,name,height)  #父类的调用
        print("女儿继承了父亲体重,母亲身高")

sp = Daughter("Jack",75,175)#Father和Mother中都有相同的方法名__init__,子类在调用时未指定,则按照从左到右的顺序查找,即调用的是Mother的方法
print(Daughter.mro())   #查看查找父类的顺序

print("名字:",sp.name)  #调用 
print("身高:",sp.height)  #调用 
print("体重:",sp.weight)  #调用   
'''
遗传父亲的体重
遗传母亲的身高
女儿继承了父亲体重,母亲身高
[<class '__main__.Daughter'>, <class '__main__.Father'>, <class '__main__.Mother'>, <class 'object'>]
名字: Jack's laopo
身高: 175
体重: 75
'''    

总结:

1、一个类可以继承多个类

2、两个父类有相同的方法名,若子类未指定继承哪一个父类,则按照从左到右的顺序查找;若指定了父类,则按照指定父类的方法

2、父类的第二种方法调用——super

super() 函数是用于调用父类的一个方法。

super() 是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序(MRO)、重复调用(钻石继承)等种种问题。

 上面的父类调用还可以这样做:

class Father:              #定义父亲这个基类
    def __init__(self,name,weight):  #定义方法,属性
        self.name = name
        self.weight = weight
        print("遗传父亲的体重")
class Mother:                    #定义母亲基类
    def __init__(self,name,height):
        self.name = name + "'s laopo"
        self.height = height
        print("遗传母亲的身高")

'''继承的顺序是先Mother后Father,即从左到右的顺序,继承了Father的weight属性和Mother的height属性'''
class Daughter(Mother,Father):
    def __init__(self,name,weight,height):

        super().__init__(name,height)  #父类的调用
        super(Mother,self).__init__(name,weight)  #父类的调用

        print("女儿继承了父亲体重,母亲身高")

sp = Daughter("Jack",75,175)#Father和Mother中都有相同的方法名__init__,子类在调用时未指定,则按照从左到右的顺序查找,即调用的是Mother的方法
print(Daughter.mro())   #查看查找父类的顺序

print("名字:",sp.name)  #调用 
print("身高:",sp.height)  #调用 
print("体重:",sp.weight)  #调用   
'''
遗传父亲的体重
遗传母亲的身高
女儿继承了父亲体重,母亲身高
[<class '__main__.Daughter'>, <class '__main__.Father'>, <class '__main__.Mother'>, <class 'object'>]
名字: Jack
身高: 175
体重: 75
'''    

3、魔法方法

3.1、什么是魔法方法?

       魔法方法就是可以给你的类增加魔力的特殊方法,如果你的对象实现(重载)了这些方法中的某一个,那么这个方法就会在特殊的情况下被 Python 所调用,你可以定义自己想要的行为,而这一切都是自动发生的。它们经常是两个下划线包围来命名的(比如 __init__,__lt__),Python的魔法方法是非常强大的,所以了解其使用方法也变得尤为重要!

#拼接
a = 'hello'
b = ' world'
print(a + b)
print(a.__add__(b))  #__add__的作用等同于‘+’

'''
执行结果:
hello world
hello world
'''



class A:
    def __add__(self, other):  #重写__add__
        print("我要飞")
a = A()
b = A()
print(a + b)

'''
执行结果:
我要飞
None
'''

 

class Rectangle:
    def __init__(self,length,width):
        self.length = length
        self.width = width

    def __add__(self, other):
        add_length = self.length + other.length  #长和长相加
        add_width = self.width + other.width    #宽和宽相加
        return add_length,add_width

a = Rectangle(3, 4)
b = Rectangle(5, 6)

print(a + b)

3.3、类的实例调用——call方法

类的实例可以向函数一样被调用吗?
class Rectangle:
    def __init__(self,length,width):
        self.length = length
        self.width  = width

    def area(self):
        areas = self.length * self.width
        return areas

    def __call__(self):
        return "this is __call__"

a = Rectangle(10,20)

print(a())       #实例对象直接调用

print("面积:",a.area())



'''
执行结果:
this is __call__
面积: 200
'''

 正常情况下,实例是不能像函数一样被调用,要想实例能够被调用,则需定义__call__ 方法

3.3、魔术方法之运算方法

3.3.1、运算符方法

__add__(self,other)    # x+y

__sub__(self,other)    # x-y

__mul__(self,other)    # x*y

__mod__(self,other)    # x%y

__iadd__(self,other)    # x+=y

__isub__(self,other)    # x-=y

__radd__(self,other)    # y+x

__rsub__(self,other)    # y-x

__imul__(self,other)    # x*=y

__imod__(self,other)    # x%=y

3.3.2、其他魔法方法

__class__    查看类名

__base__    查看继承的父类

__bases__  查看继承的全部父类

__dict__      查看全部属性,返回属性和属性值键值对形式

__doc__      查看对象文档,即类中的注释(用引号注视的部分)

__dir__        查看全部属性和方法

 

思考题:(答案见评论区)

在“定义个矩形类,有长和宽两个实例属性, 还有一个计算面积的方法”基础上,定义正方形类。 实现类实例的可调用,调用时打印边长; 同时,直接打印类实例时能够打印出实例的面积

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值