【问题标题】:Python OOB: Not understanding subclassesPython OOB:不理解子类
【发布时间】:2021-09-24 19:20:36
【问题描述】:

我目前正在学习 edube.org 的 3.2.1.10 A short Journey from procedural to object approachlab,课程(Python Essentials 2 (Intermediate, v.2.0)。

该任务是关于以面向对象的风格编写堆栈。到目前为止,我们有一个 push 和一个 pop 方法以及一个可以填充和取出最后一项的简单堆栈。现在应该扩展它以能够显示堆栈中值的总和。实验室给出的完整代码如下:

class Stack:
    def __init__(self):
        self.__stack_list = []

    def push(self, val):
        self.__stack_list.append(val)

    def pop(self):
        val = self.__stack_list[-1]
        del self.__stack_list[-1]
        return val


class AddingStack(Stack):
    def __init__(self):
        Stack.__init__(self)
        self.__sum = 0

    def get_sum(self):
        return self.__sum

    def push(self, val):
        self.__sum += val
        Stack.push(self, val)

    def pop(self):
        val = Stack.pop(self)
        self.__sum -= val
        return val


stack_object = AddingStack()

for i in range(5):
    stack_object.push(i)
print(stack_object.get_sum())

for i in range(5):
    print(stack_object.pop())

代码有效。作为使用 class AddingStack(Stack) 的解释,它说:

我们不想修改之前定义的堆栈。它已经 它的应用程序足够好,我们不希望它在任何方面发生变化 方法。我们想要一个具有新功能的新堆栈。换句话说,我们 想要构建已经存在的 Stack 类的子类。

第一步很简单:只需定义一个新的子类指向 将用作超类的类。

这就是它的样子:类添加堆栈(堆栈): 通过

该类尚未定义任何新组件,但这并不意味着 它是空的。它获取其超类定义的所有组件

但是,当我运行相同的代码时,只需将行修改为:

class AddingStack():

它仍然有效。不明白class AddingStack(Stack)有什么好处?

【问题讨论】:

  • 假设您在类Stack 中有一个size 方法。通过将AddingStack 定义为class AddingStack():,您不能调用stack_object.size()。这将引发AttributeError 异常。即使代码完全相同,您也必须在 AddingStack 中重新定义 size
  • 能否请edit 让标题更准确?我在想类似“如果这个类本身工作正常,为什么它需要成为一个子类?”
  • 附带说明,我看不到在每次推送/弹出时保持总和的运行记录的好处。 AddStack 可以很容易地让 sum 属性按需计算它。

标签: python oop inheritance


【解决方案1】:

但是,当我运行相同的代码时,只需将行修改为:

class AddingStack():

它仍然有效。我不明白 AddingStack(Stack) 类的好处是什么?

它仍然有效,因为AddingStack 中的方法显式调用了Stack 中的其他方法。

您实际上并没有使用任何继承的方法,这破坏了整个继承点。

【讨论】:

  • super() 应该改用,对吧?
  • @wjandrea 是的,super() 是调用父类行为的正确方法。
【解决方案2】:

通常,OOP 中继承的好处是能够从现有类创建一个类,并轻松稍微对其进行修改。

如果你真的只是覆盖超类中的每一个函数,那么不,不要使用继承,它不会'对你没有任何好处。

当你有一个子类,它只改变超类中的一些功能和东西时,它非常有用,其余的,将使用超类函数。

【讨论】:

    【解决方案3】:

    之所以有效,是因为您在计算总和时并未实际使用堆栈的元素,而是将结果累加到 __sum 变量中。

    您也没有使用继承,而是委托给Stack 类的pop()push() 方法。

    练习的目的似乎是让您将堆栈的元素相加(已在超类中实现)并实现get_sum(),以便您遍历堆栈上的值列表并添加他们起来。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-14
      • 2013-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多