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 语法的语言中,除了添加 get
和 set
前缀以区分两个操作之外别无选择。然而,在 Smalltalk 中,使用冒号 :
作为消息名称和参数之间的分隔符,使得使用前缀变得多余:您可以使用 balance
来读取 ivar,而 balance:
来写吧。请注意,这不仅仅是为了简单起见,它还使您的代码更接近自然语言(比较 account balance
与 account getBalance
。)
我正在用 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 语法的语言中,除了添加 get
和 set
前缀以区分两个操作之外别无选择。然而,在 Smalltalk 中,使用冒号 :
作为消息名称和参数之间的分隔符,使得使用前缀变得多余:您可以使用 balance
来读取 ivar,而 balance:
来写吧。请注意,这不仅仅是为了简单起见,它还使您的代码更接近自然语言(比较 account balance
与 account getBalance
。)