第十四天学Python:类(2):类的继承

眼看着五一假期离我越来越近,我想要休假的心情也越来越迫切,仿佛码字都变得更快乐了∑)
在昨天 什么是类.的最后面,写了一个烹饪的类,但它还是有一些问题的:
原来的方法是这么写的:

	def fry(self): #方法定义
		self.In_One = self.In_One + ' 搅匀翻炒 '
		self.In_Two = self.In_Two + ' 切片入锅 '
		return self.In_One + self.In_Two + '放盐翻炒 摆盘'

虽然看起来是可以炒一切了,但是它有个弊端就是,只能是什么什么炒鸡蛋:)如果我想做黄瓜炒木耳呢?或者茄子炖土豆呢?
强行把这个类实例化的结果可能是:

土豆 搅匀翻炒 茄子 切片入锅 放盐翻炒 摆盘:)

而这,往往是我们不希望发生的。这种时候,就需要我们改一下类的源代码——可这跟不断地自定义新函数又有什么区别呢?类本身是不是有什么改变方法/属性的技术呢?
所以!重点来了,类的继承


继承,就是在继承类原有功能的基础上,增加新的功能 / 属性 / 方法,新形成的类叫子类,被继承的叫父类

继承的基本格式

class 子类名(父类名)

在继承的时候,还可以多个父类一起继承给同一个子类,父爱如山崩地裂/doge

class 子类名(父类名1,父类名2, ....

那接下来就继承一下昨天的烹饪类/doge

继承属性、添加属性

继承属性有两种基本写法:
第一种是用super().函数,第二种则是直接用父类名继承,这两种均会在实例1种详细叙述。

实例1:继承单个方法

先回顾一下昨天的烹饪类是怎么写的

class Cook():
    def __init__(self,one,two):
        self.In_One = one
        self.In_Two = two
    def fry(self):
        self.In_One = self.In_One + ' 搅匀翻炒 '
        self.In_Two = self.In_Two + ' 切片入锅 '
        return self.In_One + self.In_Two + '放盐翻炒 摆盘'

breakfast = Cook('鸡蛋','西红柿')
print('%s'%( breakfast.fry() ))

实例化输出:

鸡蛋 搅匀翻炒 西红柿 切片入锅 放盐翻炒 摆盘

现在,我们想做茄子炖土豆了/doge,就要在原有类的基础上,继承一个新的子类,并在子类里添加炖的功能,写法如下:

class CookA(Cook):
    def __init__(self,one,two):
        super().__init__(one,two)
    def stew(self):
        return '加水,'+ self.In_One + self.In_Two + '入锅'
  • super(). :实现父类与子类的关联,当父类有参数时,就要用super()函数同步除了self以外的参数(注意括号右下角还有个点“ . ”)
  • 第一个__init__后面的参数依旧是(self,参数1,参数2…)若有增加的,则把它们也都写在里面,增加属性会在稍后讲到

子类实例化:

lunch = CookA('土豆','茄子')
print('%s'%( lunch.stew() ))

输出:

加水,土豆茄子入锅

在super的说明里,我着重强调了一下除了self以外的参数,如果我们在之前写成super(self,one,two)又会发生什么?
在这里插入图片描述
刚刚是用的super()函数来同步参数,其实除了super ,还有另一种写法:
唯一不同的就是定义属性的函数,其他的部分全部相同就不赘述了

    def __init__(self,one,two):
        Cook.__init__(self,one,two)

这种写法则是用的父类名来继承属性,不过这次就要再加上 “self” 了。

  • 如果现在的类里面,属性太少了,我们不再只是输入两个材料,我们要做一个,佛跳墙呢/doge
class CookA(Cook):
    def __init__(self,one,two,many):
        super().__init__(one,two)
        self.In_many  = many
    def stew(self):
        return '加水,'+ self.In_many +'入锅'

用父类名继承并添加元素也是同样的写法:

    def __init__(self,one,two,many):
        Cook.__init__(self,one,two)
        self.In_many  = many

实例2:继承多个方法

'''第一个类'''
class Cook()
'''继承的子类'''
class CookA(Cook):

'''写一个新的类'''
class CookB():
    def __init__(self,A,B):
        self.A = A
        self.B = B
    def fry(self):
        return '开大火爆炒'+ self.A + self.B

接下来,我们把CookA 和 CookB 作为父类(A的方法是stew,B的方法是fry),继承给 CookC
(为什么要先写B后写A?划重点,一会说)

class CookC(CookB,CookA):
    def __init__(self,one,two,many,A,B):
        CookA.__init__(self,one,two,many)
        CookB.__init__(self,A,B)

CookC的方法就不写了,直接继承AB的属性以后,我们分别调用A和B的方法:

Out = CookC('A','S','D','F','G')
print('%s'%( Out.stew() ))
print('%s'%( Out.fry() ))
加水,ASD入锅
开大火爆炒FG

而在定义CookC类的时候,先A后B呢,class CookC(CookA,CookB):

Out = CookC('A','S','D','F','G')
print('%s'%( Out.stew() ))
print('%s'%( Out.fry() ))
加水,ASD入锅
开大火爆炒AS

这是为什么?
其实用下面的例子讲更为清楚:
现在我把CookC的父类改成Cook与CookB,二者的方法都是fry,但是内容分别为:

return '加水,'+ self.In_One + self.In_Two + self.In_many +'入锅'
return '开大火爆炒'+ self.A + self.B

现在再来Out = CookC(‘A’,‘S’,‘D’,‘F’,‘G’) 以后 print(’%s’%( Out.fry() )),我们看一下输出结果:

A 搅匀翻炒 S 切片入锅 放盐翻炒 摆盘

可以发现,现在实际输出的是Cook 的fry,而不是CookB的,这是因为,当父类们有相同的方法时,默认寻找并使用从左至右开始找到的第一个方法。

实例3:重写方法

当我们发现父类的这个方法不好用的时候,我们可以在继承父类的同时重新定义一下父类的方法:(写在子类方法的下面就可)

class CookA(Cook):
    def __init__(self,one,two,many):
        Cook.__init__(self,one,two)
        self.In_many  = many
    def stew(self):
        return '加水,'+ self.In_One + self.In_Two + self.In_many +'入锅'
    def fry(self):
        return '关火,不炒了'

接下来输入材料,输出的则是重写了以后的方法

lunch = CookA('土豆','茄子','balabala')
print('%s'%( lunch.fry() ))

关火,不炒了

而这时我们不再继承父类,直接把父类实例化的话,输出还是原本的那个方法:

breakfast = Cook('鸡蛋','西红柿')
print('%s'%( breakfast.fry() ))

鸡蛋 搅匀翻炒 西红柿 切片入锅 放盐翻炒 摆盘



以上的内容其实是为了继承而继承的,如果真要一个个改也不是不行:)但这正像前文所说:这和不断地自定义新函数有什么区别?实际上,需要使用继承的原因没必要像前文那样是为了介绍而说得这么牵强,这里举两个例子各位就明白了:

  1. 这个类已经被其他程序使用了,如果改动类,相应的程序都要被牵连
  2. 有时候,我们用的第三方类,并不会提供源代码

由此才会有在遇到以上问题时,为了达到改造的目的而生的——继承 !

我是康.,立志做一名能帮助到大家的博主!在更新完Python系列后会再开机器学习的系列,对此类文章感兴趣的小伙伴欢迎与我一起学习,共同进步/doge,下篇文章见!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值