Smalltalk 中的自我和超级

Self and super in Smalltalk

我正在用 Smalltalk 编写我的第一个程序。我有一个 super class 实现了一个方法,然后是一个 sub class 继承自这个 class 并覆盖了 super class' 方法。我认为 self 语句有困难,因为当 sub class 调用该方法时,会调用 super class 和 sub class 的平衡,所以这是一种累积效应,而不是非此即彼的选择。

这是相关代码的摘录:

Object subclass: Account [

        | balance |

        ...

        getBalance [    
            ^balance
        ]

        calculateInterest [
            balance:= (self getBalance)*0.2 + self getBalance.
        ]
    ]

Account subclass: PersonalAccount [

    ... 

    calculateInterest [ 
        super calculateInterest.
        balance := (self getBalance)*0.25 + self getBalance.
    ]
]

我该如何解决这个问题?

看来您根本不需要调用 super calculateInterest

但是为了更好的设计考虑这个实现:

Object subclass: Account [

        | balance |

        ...

        getBalance [    
            ^balance
        ]

        getInterest [
            ^ 0.2
        ]


        calculateInterest [
            balance:= self getBalance * self getInterest + self getBalance.
        ]
    ]

Account subclass: PersonalAccount [

    ... 

    getInterest [
            ^ 0.25
   ]
]

或者你可以将兴趣作为参数,或者你可以将兴趣作为子class职责放在层次结构的根部,然后每个子class都应该重新定义它。

基本上你说的是:

  • 在帐户中,根据利息重新计算余额是 "xyz"
  • 在 PersonalAccount 中,根据利息重新计算余额是:
    • 首先,根据超class
    • 重新计算
    • "xyz"(稍作修改)

不要认为您必须重写方法并调用 super 想想您在描述什么。

因此,问题(据我了解)是,在您的实施中,PersonalAccount 首先应用 20% 的利息(在 super calculateInterest 中),然后再应用 25%,而打算只申请 25% 的利息。

无需在两个 类 中重复代码即可解决此问题的最佳方法是分解出 interest 方法,如下所示:

Account >> interest
    ^0.2

PersonalAccount >> interest
    ^0.25

现在,您可以从子类中删除 calculateInterest,只保留超类中的方法

Account >> calculateInterest
    balance := self getBalance * self interest + self getBalance

这样,当#calculateInterest的接收者是Account时,余额会增加20%,当接收者是PersonalAccount时,余额会增加25%.

附带说明一下,我建议将选择器 getBalance 替换为 balance。在具有类 C 语法的语言中,除了添加 getset 前缀以区分两个操作之外别无选择。然而,在 Smalltalk 中,使用冒号 : 作为消息名称和参数之间的分隔符,使得使用前缀变得多余:您可以使用 balance 来读取 ivar,而 balance: 来写吧。请注意,这不仅仅是为了简单起见,它还使您的代码更接近自然语言(比较 account balanceaccount getBalance。)