Smalltalk初始化变量 在java和C++语言中,我们给构造函数提供参数。

Smalltalk初始化变量 在java和C++语言中,我们给构造函数提供参数。,smalltalk,pharo,Smalltalk,Pharo,在Pharo Smalltalk中你是如何做到这一点的 我想要像这样的东西 |aColor| aColor = Color new 'red'. 或者这是一种糟糕的做法,我应该一直这样做吗 |aColor| aColor = Color new. aColor name:= red.d 在Smalltalk中,所有成员字段都是严格私有的,要分配给它们,必须定义分配方法 Color >> name: aString name := aString 然后您可以像这样创建对象:

在Pharo Smalltalk中你是如何做到这一点的

我想要像这样的东西

|aColor|
aColor = Color new 'red'.
或者这是一种糟糕的做法,我应该一直这样做吗

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

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

Color >> name: aString
  name := aString
然后您可以像这样创建对象:

|aColor|
aColor := (Color new)
  name: 'red';
  yourself.
|aColor|
aColor := Color withName: 'red'.
通常使用以下工厂方法来减少冗余:

Color class >> withName: aName
  ^ (self new)
    name: aName;
    yourself.
使用此选项,您可以创建如下新对象:

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

简单的回答是,你可以在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
    类消息
有很多关于Smalltalk基础知识的好书,你可以在

[*]这是很自然的,因为Smalltalk具有正交性,因为所有东西(包括类)都是对象。如果您感兴趣,请查看Smalltalk中的第13章或任何其他对类和元类的引用


HTH

更好的方法是没有任何设置器,并根据需要参数化单个初始化方法:
Color>#initializeWithName:
。在本例中,要澄清一点,类是一个对象,实例是另一个对象。为了尊重封装,该类无权访问实例的实例变量,除非通过messagesend请求。它非常统一,Smalltalk是关于发送消息的,即使对于这样的基本内核任务。。。正如Frankshearr所说,最好在实例端有一条消息同时设置所有变量,这取决于程序员的判断。