IDL 中的对象重载
原文链接: https://www.nv5geospatialsoftware.com/Learn/Blogs/Blog-Details/overloading-objects-in-idl
11580 给本文评分:
暂无评分
IDL 中的对象重载
匿名作者 2015年6月4日,星期四
大学时的一个学期,我参加了一个关于 Python 面向对象编程的非正式课程。第一天,教授问我们中是否有人有面向对象编程的经验。我告诉他我用 IDL,他不以为然地笑了,说:"IDL 不是真正的面向对象语言。"
我个人认为 IDL 具备许多面向对象的特性,并且我仍在学习新技术。由于 IDL 是一种解释型语言,我得说开发类非常容易,在 IDL 中进行面向对象编程确实没什么好怕的。
在本周的 IDL Data Point 文章中,我将讨论重载现有类的操作符。IDL 中的任何对象,包括安装时提供的对象,都可以通过编写一个在对象类定义中使用 inherits 关键字的新对象类来重载。事实上,有些对象,例如 IDL_OBJECT,就是专为被重载而设计的。
下面是一个我编的例子:我想使用一个列表(List),但我希望我的列表比 IDL 中简单的 LIST 对象功能更强一点(注意 IDL 文档将列表和哈希表指定为"复合数据类型",但在底层,它们就是对象类)。这个花哨的列表只允许添加数字。它还必须具备将所有值乘以指定因子的能力,以及将所有值递增一的能力。
定义类
由于想不出更好的名字,我将这个新列表称为 "Fancy_List"。其定义如下:
pro Fancy_List__Define !null = {Fancy_List, inherits List} end
现在,"Fancy_List" 被定义为一个列表的子类。
fl = Obj_New('Fancy_List') PRINT, Isa(fl, 'List')
IDL 打印出 1。
这意味着一个花哨的列表 就是 一个列表,而且是一个非常花哨的列表。
重载 ::Add 方法
由于这个列表只应允许数值,因此需要重载 Add 方法。这可以通过编写一个 Fancy_List::Add 方法来实现。在本例中,任何传入的非数值将被静默忽略。执行检查后,代码随后调用其父类的 ::Add 方法。关键字参数则通过 _REF_EXTRA 原样传递(这里使用 _REF_EXTRA 而不是 _EXTRA,是为了避免不必要的关键字副本)。
pro Fancy_List::Add, value, index, _REF_EXTRA=extra if ~Isa(value, /NUMBER) then return self.List::Add, value, index, _EXTRA=extra end
实现 ::Multiply 方法
我将编写一个名为 ::Multiply 的新方法,将所有值乘以给定的因子。这个方法名是花哨列表独有的,因为 LIST 没有这样的方法,所以它并不重载任何东西。
pro Fancy_List::Multiply, multiplier for i=0, self.Count()-1 do begin self[i] *= multiplier endfor end
重载操作符
由于 List 继承自 IDL_Object,而 Fancy_List 又继承自 List,因此这个花哨的列表可以重载 IDL_Object 的任何操作符。以下是重载 ++ 操作符的示例。此操作将使花哨列表中的每个值递增一。
pro Fancy_List::_overloadPlusPlus for i=0, self.Count()-1 do begin self[i]++ endfor end
运行示例
现在所有部分都组装好了,我们点击 Compile 按钮来试试吧!
fl = Fancy_List() fl.Add, 'A' print, fl.Count()
IDL 打印出 0,因为花哨列表忽略了字符串值 'A'。
fl.Add, [1,2,3,4], /EXTRACT PRINT, fl
IDL 打印出:
1 2 3 4
fl.Multiply, 2
PRINT, fl
IDL 打印出:
2 4 6 8
fl++ PRINT, fl
IDL 打印出:
3 5 7 9