smalltalk中的内部类

smalltalk中的内部类,smalltalk,inner-classes,Smalltalk,Inner Classes,我想知道为什么smalltalk不使用java风格的内部类。这种机制有效地允许您在需要时在需要的地方动态地定义新类的新实例。当您需要一个符合特定协议的对象,但又不想为其创建一个普通类时,它非常方便,因为它的临时性和局部性是非常特定于实现的。 据我所知,这样做很容易,因为子类化的语法是标准的消息发送。你可以把自我传递给它,这样它就有了“外部”物体的概念。唯一的问题是匿名性-该类不应出现在对象浏览器中,并且必须在没有实例退出时进行垃圾收集。 问题是:有人想过这个吗?我很肯定,通过对类和元类协议进行一

我想知道为什么smalltalk不使用java风格的内部类。这种机制有效地允许您在需要时在需要的地方动态地定义新类的新实例。当您需要一个符合特定协议的对象,但又不想为其创建一个普通类时,它非常方便,因为它的临时性和局部性是非常特定于实现的。 据我所知,这样做很容易,因为子类化的语法是标准的消息发送。你可以把自我传递给它,这样它就有了“外部”物体的概念。唯一的问题是匿名性-该类不应出现在对象浏览器中,并且必须在没有实例退出时进行垃圾收集。
问题是:有人想过这个吗?

我很肯定,通过对类和元类协议进行一些黑客攻击,就可以做到这一点。这个问题经常从对Java有更多经验的人那里冒出来,Smalltalk对他们来说变得很有趣。由于内部类尚未实现,我认为这是大多数Smalltalk用户发现它们不可用的迹象。这可能是因为Smalltalk有块,它以更简单的方式解决了导致Java引入内部类的许多问题(如果不是所有的话)。

我敢肯定,通过对类和元类协议进行一些黑客攻击就可以做到这一点。这个问题经常从对Java有更多经验的人那里冒出来,Smalltalk对他们来说变得很有趣。由于内部类尚未实现,我认为这是大多数Smalltalk用户发现它们不可用的迹象。这可能是因为Smalltalk有块,以更简单的方式解决了导致Java引入内部类的许多问题(如果不是所有的话)。

(a)您可以发送消息,从另一个类的方法内部创建一个新类

(b) 我怀疑在内省系统中隐藏结果类是否有任何好处

(c) 在Java中使用内部类的原因是因为没有一流的函数。如果需要在Smalltalk中传递一段代码,只需传递一个块。您不需要使用其他类型的对象来包装它。

(a)您可以发送消息,从另一个类的方法内部创建一个新类

(b) 我怀疑在内省系统中隐藏结果类是否有任何好处

(c) 在Java中使用内部类的原因是因为没有一流的函数。如果需要在Smalltalk中传递一段代码,只需传递一个块。您不需要使用其他类型的对象来包装它。

问题(至少在Squeak中)来自于缺乏清晰的关注点分离。创建自己的子类并将其放入私有的
SystemDictionary
,这很简单:

myEnv := SystemDictionary new.
myClass := ClassBuilder new
    name: 'MyClass'
    inEnvironment: myEnv
    subclassOf: Object
    type: #normal
    instanceVariableNames: ''
    classVariableNames: ''
    poolDictionaries: ''
    category: 'MyCategory'
    unsafe: false.  
但是,即使您将该类放入自己的
SystemDictionary
,“MyCategory”类别添加到系统导航中(可通过打开
浏览器进行验证),更糟糕的是,没有创建类组织者,因此当您导航到
MyClass
时,您会得到一个零指针

理论上,这当然不是不可能的。目前,该工具面向一个全局可见的类定义池。

问题(至少在Squeak中)来自于缺乏清晰的关注点分离。创建自己的子类并将其放入私有的
SystemDictionary
,这很简单:

myEnv := SystemDictionary new.
myClass := ClassBuilder new
    name: 'MyClass'
    inEnvironment: myEnv
    subclassOf: Object
    type: #normal
    instanceVariableNames: ''
    classVariableNames: ''
    poolDictionaries: ''
    category: 'MyCategory'
    unsafe: false.  
但是,即使您将该类放入自己的
SystemDictionary
,“MyCategory”类别添加到系统导航中(可通过打开
浏览器进行验证),更糟糕的是,没有创建类组织者,因此当您导航到
MyClass
时,您会得到一个零指针


理论上,这当然不是不可能的。现在,该工具面向一个全局可见的类定义池。

如果您正在考虑使用内部类进行测试,那么如果您正在考虑使用内部类进行测试,那么您还可以查看类FactoryforTestCase

,然后,您还可以查看ClassFactoryForTestCase类

在smalltalk中创建匿名类很容易。 更重要的是,任何对象只要将其实例变量的3个正确设置为:其超类、方法字典和实例格式,就可以作为一个类(have instances)。 所以,我不明白这里的问题是怎么回事


如果您谈论的是工具支持,比如浏览或导航这些类中包含的代码,那么情况就不同了。因为默认情况下,系统中的所有类都是公共的,并且系统字典是它们的一个平面名称空间(是的,有些实现有名称空间)。这个简单的模型在大多数情况下都运行得很好

在smalltalk中创建匿名类是小菜一碟。 更重要的是,任何对象只要将其实例变量的3个正确设置为:其超类、方法字典和实例格式,就可以作为一个类(have instances)。 所以,我不明白这里的问题是怎么回事


如果您谈论的是工具支持,比如浏览或导航这些类中包含的代码,那么情况就不同了。因为默认情况下,系统中的所有类都是公共的,并且系统字典是它们的一个平面名称空间(是的,有些实现有名称空间)。这个简单的模型在大多数情况下都运行得很好

这里有两个答案:

1-是的,创建自动收集垃圾的匿名类并不难。在Squeak中,它们被称为“Uniclass”,因为典型的用例是向单个对象添加方法。使用此功能的系统例如Etoys和Tweak(尽管在Etoys中,由于历史原因,类实际上被放入SystemDict中)。下面是我最近使用的一些吱吱声代码:

newClass := ClassBuilder new
    newSubclassOf: baseClass
    type: baseClass typeOfClass
    instanceVariables: instVars
    from: nil.
baseClass removeSubclass: newClass.
^newClass
通常,您会添加一个conv