smalltalk - 如何将对象的类型存储在变量中?
问题描述
我有一个需要传递元素类型的类,因此我可以稍后检查另一个对象是否具有该类型或者是该类型的子类并将其添加到内部集合中。
我有一个从我的班级的ctorinitialize:
调用的方法:new:
initialize: aType
elements := OrderedCollection new.
type := aType class.
现在我有一个方法可以传递一个值,并且应该检查类型是否兼容:
add: anElement
type isNil ifTrue: [ elements add:anElement. ^self. ].
(anElement isMemberOf: type)
ifTrue: [elements add:anElement.]
ifFalse: [ ^ 'Not supported!' ].
如果我想检查具体类型,这很有效:
|myClass|
myClass:= MyClass new: '123'.
cc add: '5.4'. "Works"
cc add: 123. "Fails correctly."
现在,为了检查它是否是派生类型,我修改了add:
方法:
add: anElement
type isNil ifTrue: [ elements add:anElement. ^self. ].
(anElement isKindOf: type)
ifTrue: [elements add:anElement.]
ifFalse: [ ^ 'Not supported!' ].
但是,这不起作用:
|myClass|
myClass:= MyClass new: 5 asNumber.
myClass add: 5.4. "Fails, although Float is a sub type of Number"
我怀疑我最初确定对象类型 ( aType class
) 的方法是错误的,但我找不到更好或更明确的确定类型的方法。基本上,我正在寻找类似typeOf(MyObject)
C# 的东西。这是练习的一部分,所以请原谅人为的例子:)
解决方案
正如我在对您的问题的评论中提到的那样,问题在于5 asNumber
哪个5
是 的实例SmallInteger
,而不是Number
. 因此,当您在 ivar 中获得initialize:
的课程是. 然后,当 you 时,检查变为,自然会失败。5
type
SmallInteger
add: 5.4
5.4 isKindOf: SmallInteger
我认为问题出在您选择初始化实例的方式上。一种更简单的方法是type
使用类而不是实例显式设置目标。有点意思
initialize: aClass
elements := OrderedCollection new.
type := aClass
然后,您的示例将类似于
|myClass|
myClass:= MyClass new initialize: Number.
myClass add: 5.4.
which 可以5.4
作为一个元素接受,因为它是 a Float
, which isKindOf: Number
。
现在让我再补充一句。通常的语义与new:
您使用的不同。的参数new:
通常是一个Integer
和这样的整数表示新实例的所需大小。例如,您说Array new: 3
当您想要一个Array
带有3
条目等时。不期望new:
接收其他类型的参数来构造对象。我并不是说这是禁止的,只是这不是通常的命名约定。在您的情况下,我会建议一种创建实例的方法,例如
MyClass class >> on: aClass
^self new initialize: aClass
你的代码看起来像
| sequence |
sequence := MyClass on: Number.
sequence add: 5. "ok, 5 isKindOf: Number"
sequence add: 4.5. "ok, 5.4 isKindOf: Number"
sequence add: 'hello world' "fail, not a Number"
推荐阅读
- excel - 列出文件夹中的文件 excel onedrive
- firebase-authentication - Google / DialogFlow 上的操作:从没有转换对象的 idToken 获取用户数据
- firebase - Firebase 好友列表关系
- jquery - jquery对图像没有响应的爆炸效果
- javascript - 为什么当我通过 fetch API 请求记录我的 React 状态 setState 时会收到两个响应?
- java - 有没有办法使用 Apache Commons Digester 从 xml 中添加 Arraylist 中键的所有值?
- ios - 图像不是从一个 VC 到另一个 VC
- matlab - 如何在 matlab 或 simulink 中对组合(电气和机械)系统执行鲁棒控制
- python - Python 单元测试 - 运行时的模拟补丁?
- aws-lambda - 带有 API Gateway 的 AWS Lambda 返回 500 错误并带有 hello-world 蓝图