我在玩J的面向对象工具。考虑以下极其人为的代码:
coclass 'Object'
create =: 3 : 'state =: 0'
increment =: 3 : 'state =: state + y'
destroy =: codestroy
cocurrent 'base'
objects =: (0 conew 'Object') , (0 conew 'Object') , 0 conew 'Object'
假设我要increment
在objects
数组中的每个对象上调用该方法。我该如何以J-tastic方式进行操作?我想出的唯一方法是中间动词:
o_increment =: 4 : 0
for_o. y do.
increment__o x
end.
)
3 o_increment objects
这可行,但不是很方便。有没有更好的办法?
因为对象引用是J的形态的一部分,而不是语法,所以在运行时比其他数据更难操作。也就是说,对象引用被烘焙为名称,而不是被指定为自由参数。
因此,有两种方法可以在对象数组上调用方法,并且都需要显式代码。第一种方法(除非在特殊情况下很少使用)是生成然后执行代表完全限定名称的字符串,包括直接(显式)位置。
3 apply&>~ 'increment_' ,L:0 objects ,&.> '_'
更常见的是在显式代码块中使用间接引用,将预定义的局部变量之一用作位置。例如:
3 dyad def 'increment__y x'"0 objects
或等效地:
incrementObjs =: dyad define
increment__x y
)
objects incrementsObjs"0] 3
实际上,JSoftware专门对版本6中的语言进行了重大的向后兼容突破性更改,以使此模式更加方便。以前(即v6之前),您将不得不编写以下内容:
incrementObjs =: dyad define
o =. x. NB. x and y used to be spelled x. and y.
increment__o y NB. but increment__x. would raise an error
)
无论如何,请注意,incrementsObjs"0 objects
您对显式for_o. objects do.
循环的这种表述实际上根本不是特定于OOP的。它是J的面向数组性质提供的标准的迭代自动化。
这使我真正回答了您的问题:J本质上是一种面向数组的语言,它的对象通常比Java或C#等更熟悉的语言中的对象更粗糙。
在这些语言中,通常有一个对象集合。在J中,拥有集合的对象更为常见。也就是说,从某种意义上说,主流OOP语言中的对象是“小”的。在J中,对象很大,因为J中的所有数据都很大(我不是在物理的“大数据”中,GB的意思是:从概念上,哲学上,ℕ上来说)。
因此,表达您的问题的最常用方法是:
coclass 'Object'
create =: 3 : 'state =: 0'
increment =: 3 : 'state =: state + y'
destroy =: codestroy
cocurrent 'base'
objects =: 'Object' conew 0 0 0
注意最后一行objects =: 'Object' conew 0 0 0
; 原来是objects =: (0 conew 'Object') , (0 conew 'Object') , 0 conew 'Object'
。
那就是:我们创建了一个具有3个值的数组的对象,而不是3个对象的数组。
还请注意,这是我更改的唯一代码行。从处理标量值的对象到管理任意数量的值的数组的“重构”花费了零字节的代码更改。
但是增加所有对象呢?以前,您不得不说:
3 dyad def 'increment__y x'"0 objects
现在,您只需要说:
increment__objects 3
这就是为什么这是J 1中OOP的标准方法。
1嗯,一个愤世嫉俗者可能会说,J的基本排列性质以某种方式消除或者甚至冲突与OOP的目标,那OO可用以J特色OOP在90年代末的权势期间条条框框作为一种事后咳嗽Perl咳嗽,但我并不愤世嫉俗。至少不是公开的。
OOP在J中占有一席之地,特别是在组织动态系统中的大型组件时。它的使用方式与基本概念是OO而不是AO的语言不同。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句