【问题标题】:Smalltalk initialization variablesSmalltalk 初始化变量
【发布时间】:2013-01-08 21:49:17
【问题描述】:

在 Java 和 C++ 等语言中,我们为构造函数提供参数。

您如何在 Pharo Smalltalk 中做到这一点?

我想要类似的东西

|aColor|
aColor = Color new 'red'.

或者这是不好的做法,我应该总是这样做

|aColor|
aColor = Color new.
aColor name:= red.d

【问题讨论】:

    标签: smalltalk pharo


    【解决方案1】:

    简短的回答是,您可以在 Smalltalk 中做几乎相同的事情。从调用代码来看,它看起来像:

    aColor := Color named: 'Red'.
    

    长答案是,在 Smalltalk 中您没有构造函数,至少在某种意义上没有以类命名的特殊消息。您在 Smalltalk 中所做的是定义类端消息(即类理解的消息,而不是实例 [*]),您可以在其中实例化和配置实例。假设你的Color 类有一个name 实例变量和一个setter,#named: 方法的实现方式如下:

    (class) Color>>named: aName
    | color |
    color := self new.
    color name: aName.
    ^color.
    

    注意事项:

    • 我们正在使用发送到类的#new 消息来创建一个新实例。您可以将#new 消息视为创建对象的原始方式(提示:您可以浏览#new 消息的实现者以了解它是如何实现的)。
    • 我们可以定义任意数量的类方法来创建新的“已配置”实例(例如Color fromHexa:)或返回预先创建的实例(例如Color blue)。
    • 您仍然可以通过执行Color new 创建未初始化的实例。如果您想禁止该行为,则必须覆盖 #new 类消息。

    您可以在Stef's Free Online Smalltalk Books阅读很多关于 Smalltalk 基础知识的好书

    [*] 由于 Smalltalk 的正交特性,这很自然,因为一切(包括类)都是对象。如果您有兴趣,请查看Pharo by Example 的第 13 章或任何其他对 Smalltalk 中的类和元类的参考。

    HTH

    【讨论】:

    • 更好的是没有任何设置器,并且根据需要参数化单个初始化方法:在这种情况下为Color >> #initializeWithName:
    • 澄清一点,类是一个对象,实例是另一个对象。为了尊重封装,该类无法访问实例的实例变量——除非通过消息发送请求。它非常统一,Smalltalk 是关于发送消息,即使对于这样的基本内核任务......正如 FrankShearar 所说,在实例端有一条消息可能会更好地同时设置所有变量,这取决于程序员来判断。
    【解决方案2】:

    在 Smalltalk 中,所有成员字段都是严格私有的,要分配给它们,您必须定义分配方法。

    Color >> name: aString
      name := aString
    

    然后你可以像这样创建你的对象:

    |aColor|
    aColor := (Color new)
      name: 'red';
      yourself.
    

    通常使用工厂方法来减少冗长:

    Color class >> withName: aName
      ^ (self new)
        name: aName;
        yourself.
    

    有了这个,你可以像这样创建新对象:

    |aColor|
    aColor := Color withName: 'red'.
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-01
      • 2019-05-17
      • 2021-07-08
      • 2012-06-15
      • 2012-10-19
      • 2016-11-03
      • 2017-03-20
      • 2016-07-31
      相关资源
      最近更新 更多