【问题标题】:Why is it called operator overloading and not overriding in Python?为什么在 Python 中称为运算符重载而不是覆盖?
【发布时间】:2017-07-28 15:32:16
【问题描述】:

如果我想改变继承方法的行为,我会这样做:

class a:
    def changeMe(self):
        print('called a')

class b(a):
    def changeMe(self):
        print('called b')

我相信这是 Python 中覆盖的一个例子。

但是,如果我想重载一个运算符,我会做一些非常相似的事情:

class c:
    aNumber = 0
    def __add__(self, operand):
        print("words")
        return self.aNumber + operand.aNumber

a = c()
b = c()
a.aNumber += 1
b.aNumber += 2
print(a + b) # prints "words\n3"

我想也许操作符方法在 python 中真的被重写了,因为我们重载了using optional parameters,我们只是把它称为操作符重载。

但它也不能被覆盖,因为'__add__' in object.__dict__.keys()False;方法必须是父类的成员才能被覆盖(所有类在创建时都继承自 object)。

我的理解差距在哪里?

【问题讨论】:

  • 我相信覆盖通常是指采用已经存在的方法并覆盖它以用于您的特定实现。运算符重载通常采用语言中的运算符,即“+”,并为通常没有内置操作的对象定义它们。例如,如果我创建一个名为“item”的类,它有一个价格和一个描述,我可以使用运算符重载来定义 item1 + item2 的作用,这可以说...返回组合价格。
  • 请在 changeme 函数签名中使用 self。 a类:def changeme(self):print('称为a')b类(a):def changeme(self):print('称为b')

标签: python python-3.x oop operator-overloading overriding


【解决方案1】:

我想既然最初的问题专门询问了我自己的理解差距,我最适合回答它。去图吧。

我不明白的是,虽然覆盖依赖于继承,但重载则不然。而是Python matches methods for overloading based on name only

要让子类覆盖一个方法,该方法确实需要存在于父类中。因此,def __add__ 部分不是覆盖示例。

(在这种情况下,我也没有完全理解,如果解释器看到+ 运算符,它会在操作数的类中查找__add__ magic method 的定义。)

因为+ 运算符本质上是__add__() 的别名,所以使用了相同的名称。运算符重载实际上是重载的一个示例,因为当使用新参数(在我的示例中,类 c 的对象)调用名称(+__add__)时,我们正在更改名称的行为。

【讨论】:

  • 这正是我想要理解的。谢谢。
【解决方案2】:

重载意味着 2 个具有相同名称和不同签名 + 返回类型的方法。覆盖是指具有相同名称的两个方法,其中子方法具有不同的功能。重载和覆盖之间的主要区别在于,在重载中,我们可以在一个类上为不同的任务多次使用相同的函数名和不同的参数。覆盖意味着我们可以在派生类中使用具有相同参数的基类的同名函数名。这也称为程序中代码的可重用性。

【讨论】:

  • 我同意你写的一切,除了最后一句话:代码重用与重载或覆盖无关。代码可以在执行这两种方法时重复使用,但您也可以在不重复使用任何代码的情况下实现它们中的任何一种。
  • 是的,老板完全同意你的看法。认为在这方面需要进行一些修改
猜你喜欢
  • 1970-01-01
  • 2011-07-14
  • 1970-01-01
  • 1970-01-01
  • 2019-07-05
  • 2021-07-23
  • 2018-07-14
  • 1970-01-01
  • 2011-02-09
相关资源
最近更新 更多