python类的继承及重写父类方法

本文详细介绍了Python中类的继承与父类方法的重写。通过具体实例,展示了如何定义基类与派生类,以及如何在派生类中重写基类的方法。同时,还讲解了super函数在Python2和Python3中的不同用法,以及如何通过super调用父类的方法。

python类的继承及重写父类方法


写python有一年多了,平日使用Python解决一些问题,调一些接口,用一些框架,虽然不影响都可以写,但一直没有好好的花时间去理解Python概念性的东西。也许,这也是写了这么久一直不能有所进步的原因,从今天起,来重新好好的学习一下Python的相关概念。


1.类的继承,我们先来写两个类,他们之间为包含关系。类A为(Tree)树,类B为(Apple)苹果树,类C为(Pear)梨子树

class Tree:
	def __init__(self,name,age):
		self.name = name
		self.age = age

	def grow(self):
		print("{} tree is growing...now it's {} years old".format(self.name,self.age))


	def seed(self):
		print("{} tree is seeding...".format(self.name))


class Apple(Tree):
	"""docstring for ClassName"""
	def __init__(self, name, age, color):
		super().__init__(name,age)
		self.color = color


	def price(self):
		print("One {} tree is 100 dollars".format(self.name))


class Pear(Tree):
	"""docstring for ClassName"""
	def __init__(self, name, age, color):
		super().__init__(name,age)
		self.color = color

	def price(self):
		print("One {} {} tree is 80 dollars".format(self.color,self.name))
		

	def grow(self):
		#重写父类的方法grow生长
		print("it was {} years old,now it is {} years old".format(self.age,int(self.age)+1))


if __name__ == '__main__':
	a = Apple('White Apple',8,'white')
	a.grow()
	a.seed()
	a.price()
	b = Pear('Pear',8,'red')
	b.price()
	b.grow()
>>>
#White Apple tree is growing...now it's 8 years old
#White Apple tree is seeding...
#One White Apple tree is 100 dollars
#One red Pear tree is 80 dollars
#it was 8 years old,now it is 9 years old

2.类Tree是各种树的总称,可理解为苹果树,梨子树等抽象后的上层概念。类Apple和类Pear都继承了类Tree,其中self.nameself.age是父类Tree的属性,self.color是子类Apple和Pear的属性。通过继承,Apple和Pear可以直接使用父类的方法和属性。

3.父类方法的改写,可通过在子类中重写相同函数名的方式进行改写。

class Tree:
	...
	...
	def grow(self):
		print("{} tree is growing...now it's {} years old".format(self.name,self.age))
		
class Pear(Tree):
	···
	···
	def grow(self):
		#重写父类的方法grow生长
		print("it was {} years old,now it is {} years old".format(self.age,int(self.age)+1))

4.super函数的用法

  • python2和python3中的区别
python2 super(Tree,self).__init__(name,age)
python3 super().__init__(name,age)

在子类中使用super()函数,super()函数可以见到理解为代表父类Tree()。当需要在子类中调用父类的方法时,我们可以用super()来表示父类Tree()

···
···
class orange(Tree):
	def grow(self):
		#调用父类Tree的方法grow
		super().grow()
		#直接调用Tree类的方法
		Tree('Apple','16').grow()
		#重写父类方法grow
		print("{} tree has changed...".format(self.name))


orange('orange','15')
>>>
#orange tree is growing...now it's 15 years old
#Apple tree is growing...now it's 16 years old
#orange tree has changed...		
  • Python允许多重继承例如class fruits(Apple,Tree)的用法,多重继承容易出现父类方法多次调用的问题,可以通过super的使用来确保父类方法只被调用一次。python类的继承顺序是根据MRO,通过C3算法来计算的。我的理解当出现类方法的多次调用时,super会确保执行距离子类最近的所继承的父类的方法。对该问题感兴趣,可以深入了解砖石继承和super。总之,不是必须一般不推荐使用多重继承
<think>我们正在讨论Python重写父类的含参方法。根据用户提供的引用,特别是引用[2]和引用[3],我们知道重写父类方法时,子可以定义与父类同名的方法,并且如果需要保留父类的功能,可以使用super()来调用父类方法,然后添加子特有的功能。重写带参数的方法重写无参数方法似,但需要注意在子方法中正确地传递参数。 步骤: 1.在子中定义与父类同名的方法,包括相同的参数(参数名可以不同,但数量和含义应一致)。2.在子方法中,如果需要调用父类的原方法,使用super().方法名(参数)来调用,并传入相应的参数。3.添加子特有的代码。 示例: 假设有一个父类Animal,其中有一个带参数的方法:```pythonclassAnimal:defeat(self, food):print(f"动物吃{food}")``` 现在,我们创建一个子Dog,重写eat方法,在调用父类方法前后添加一些行为: ```pythonclass Dog(Animal):def eat(self,food):#子特有的行为print("狗看到食物摇尾巴")#调用父类的eat方法super().eat(food)#子特有的行为print("狗吃完了,汪汪叫")#创建Dog对象并调用eat方法dog= Dog() dog.eat("骨头") ```输出:``` 狗看到食物摇尾巴动物吃骨头狗吃完了,汪汪叫``` 注意:-参数传递:子方法中的参数需要传递给父类方法,如上例中的`food`。-如果父类方法有多个参数,子方法需要相应定义这些参数,并在调用super时传递。特殊情况:如果子方法需要改变参数的数量或型,那么需要谨慎设计,因为这可能违反里氏替换原则。通常,子方法应该保持与父类方法相同的接口(参数数量和型),但可以有不同的实现。另外,引用[4]提到,如果父类方法是私有方法(以双下划线开头),则不能直接重写,因为Python会进行名称修饰。但通常我们不建议重写私有方法。因此,重写父类的含参方法的关键是保持参数一致,并在需要时使用super()调用父类方法。相关问题:1.在重写父类方法时,如何确保父类方法被正确调用?2.重写方法时参数不一致会导致什么问题?3.在Python中,如何防止子重写父类的特定方法?</think>### 如何在Python重写父类的含参方法Python重写父类的含参方法需要遵循以下关键步骤: #### 1. **定义同名方法** 在子中创建与父类**同名且参数列表相同**的方法: ```python class Parent: def calculate(self, a, b): # 父类含参方法 return a + b class Child(Parent): def calculate(self, x, y): # 子重写同名方法 return super().calculate(x, y) * 2 # 调用父类方法并扩展 ``` #### 2. **正确传递参数** 通过`super()`调用父类方法时,**必须显式传递所有参数**: ```python class Child(Parent): def calculate(self, num1, num2): # 正确传递参数给父类方法 parent_result = super().calculate(num1, num2) return parent_result ** 2 ``` #### 3. **参数扩展(可选)** 如需扩展参数,建议保持基础参数一致,通过`*args/**kwargs`处理额外参数: ```python class Child(Parent): def calculate(self, a, b, scale=1): # 添加新参数 result = super().calculate(a, b) return result * scale # 使用新参数扩展功能 ``` #### 4. **完整示例** ```python class Vehicle: def move(self, distance, speed): # 父类含参方法 print(f"移动{distance}公里,时速{speed}km/h") class Car(Vehicle): def move(self, dist, spd, fuel_consumption): # 重写并添加新参数 super().move(dist, spd) # 调用父类方法 print(f"油耗:{dist * fuel_consumption}升") # 使用示例 my_car = Car() my_car.move(100, 60, 0.08) # 距离,速度,油耗系数 ``` 输出: ``` 移动100公里,时速60km/h 油耗:8.0升 ``` #### 关键注意事项: 1. **参数一致性**:子方法参数应与父类**基础参数数量和型匹配**,否则会破坏多态性[^2] 2. **super()使用**:必须通过`super().method(args)`调用父类实现,直接写父类名可能导致继承问题[^3] 3. **私有方法**:双下划线方法(如`__method`)会被名称修饰,不建议重写[^4] 4. **参数命名**:子参数名可与父类不同,但**位置顺序必须一致** > 通过重写含参方法,子可扩展父类行为:保留核心功能(通过super调用)的同时添加新特性,实现"扩展式重写"[^2][^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值