python基础学习-继承

自学的小记录,大佬绕道

1、一个子类可以继承它的父类的所有属性和方法

先看一个具体的例子

# 继承
class Parent:
  def hello(self):
    print('调用父类的hello方法')

# class DerivedClassName(BaseClassName):
class Child(Parent):
  pass # 直接向下执行

p = Parent()
c = Child()

p.hello()
# c.hello()



在这里插入图片描述
在这里插入图片描述

我们发现直接调用c.hello也能执行父类中的方法,这说明一个子类可以继承它的父类的所有属性和方法
在这里插入图片描述

2、如果子类中定义与父类同名的方法或属性,则会自动覆盖父类对应的方法和属性(即子类方法属性改变,父类是不变的)

# 继承:一个子类可以继承它的父类的所有属性和方法
class Parent:
  def hello(self):
    print('调用父类的hello方法')

# 如果子类中定义与父类同名的方法或属性,则会自动覆盖父类对应的方法和属性(即子类方法属性改变,父类是不变的
class Child(Parent):
  def hello(self):
    print('调用子类的hello方法')

p = Parent()
c = Child()

p.hello()
c.hello()

运行结果
在这里插入图片描述
这里覆盖是子类实例对象里面的方法,父类是不受影响的

3、子类方法覆盖父类的解决方法

这里举一个简单的小例子,通过定义一个鱼的大类和不同种类的鱼,定义他们的移动、吃的方法。


import random as r

# 鱼的大类
class Fish:
  def __init__(self):
      self.x = r.randint(0, 10)
      self.y = r.randint(0, 10)
  def move(self):
      self.x -= 1
      print("目前的位置是", self.x, self.y)

# 金鱼
class Goldfish(Fish):
    pass
# 鲤鱼
class Garp(Fish):
    pass
# 三文鱼
class Salmon(Fish):
    pass
# 鲨鱼
class Shark(Fish):
  def __init__(self):
        self.hungry = True

  def eat(self):
      if self.hungry:
          print('继续吃')
          self.hungry = False
      else:
          print('吃不下')


fish = Fish()
goldfish = Goldfish()
shark = Shark()
# 移动
fish.move()
goldfish.move() # 继承父类的方法
shark.eat() # 调用子类的方法

运行结果
在这里插入图片描述
可以看到,目前我们无论是调用父类的方法还是子类的方法,都能成功调用。
接下来我们调用

shark.move()

出现了报错
在这里插入图片描述
shark对象没有x这个属性
后来发现

class Shark(Fish):
# 这里重写了方法,会把父类当中的方法覆盖掉,导致无法获取x、y的属性
  def __init__(self):
        self.hungry = True

这里重写了方法,会把父类当中的方法覆盖掉,导致无法获取x、y的属性

为解决这个问题,有两种解决方法
(1)调用未绑定的父类方法

# 鲨鱼
class Shark(Fish):
# 这里重写了方法,会把父类当中的方法覆盖掉,导致无法获取x、y的属性
  def __init__(self):
      Fish.__init__(self) # 调用父类的方法,但是这里的self还是指向子类,相当于Fish.__init__(shark)
      self.hungry = True

  def eat(self):
      if self.hungry:
          print('继续吃')
          self.hungry = False
      else:
          print('吃不下')

在这里插入图片描述
运行结果
在这里插入图片描述
没有报错

(2)使用super函数(super函数会帮我们自动找到基类的方法,而且还自动为我们传入self参数)
这个方法其实更便于理解和使用

# 鲨鱼
class Shark(Fish):
# 这里重写了方法,会把父类当中的方法覆盖掉,导致无法获取x、y的属性
  def __init__(self):
      super().__init__()
      self.hungry = True

  def eat(self):
      if self.hungry:
          print('继续吃')
          self.hungry = False
      else:
          print('吃不下')

运行结果
在这里插入图片描述
同样也可以解决这个问题。super函数的方便之处就在于不用给定任何基类的名字,但是它会帮我们自动找到基类中对应的方法。(这里的一个好处就是如果我们采用第一种方法,当我们父类的名字改变时,我们需要改变子类中每一处使用init方法的地方:Fish.init(self),但是如果用super方法可以省去很多麻烦)

4、多重继承

在这里插入图片描述
下面用一个例子来具体说明

# 多重继承
class Base1:
  def foo1(self):
    print("Base1的foo1")

class Base2:
  def foo2(self):
    print("Base2的foo2")

# 多重继承
class C(Base1, Base2):
  pass

c = C()
c.foo1()
c.foo2()

在这里插入图片描述
这里的c继承了Base1、Base2,可以继承他们的属性和方法,但是实际上多重继承很容易造成混乱,所以如果非必要不要使用多继承

猜你喜欢

转载自blog.csdn.net/m0_47146037/article/details/120758535