DAVE的IDL教程(二)
面向对象编程
DATA__DEFINE.PRO
- data__define
- data::display
- data::getProperty
- data::cleanup
- data::init
语法高亮在处理$时存在问题,有些代码行被砍掉了,只好放弃语法高亮
; DATA__DEFINE.PRO
;
; DATA object class.
;
; Written by R.M. Dimeo (12/03/02)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro data::cleanup
ptr_free,self.dataPtr
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro data::getProperty, nchan = nchan, $
ngroups = ngroups
if arg_present(nchan) then nchan = self.nchan
if arg_present(ngroups) then ngroups = self.ngroups
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro data::display,colorTable = colorTable
if n_elements(colorTable) ne 0 then self.colorTable = colorTable
loadct,self.colorTable,/silent
xsize = 400 & ysize = 400
if self.winId eq (-1L) then begin
window,/free,xsize = xsize,ysize = ysize
self.winId = !d.window
endif else begin
wset,self.winId
endelse
tv,smooth(congrid(bytscl(*self.dataPtr),xsize,ysize),10)
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro data::changeCT,colorTable
self->display,colorTable = colorTable
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function data::init,data
device,decomposed = 0
loadct,0,/silent
dsize = size(data)
self.nchan = dsize[1]
self.ngroups = dsize[2]
self.dataPtr = ptr_new(data,/no_copy)
self.colorTable = 0
self.winId = -1L
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro data__define
define = { data, $
nchan:0, $
ngroups:0, $
winId:0L, $
colorTable:0, $
dataPtr:ptr_new() $
}
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
d1 = hanning(40,20) & d2 = dist(60,60)
o1 = obj_new('data',d1)
help,/heap,/brief
Heap Variables:
# Pointer: 1
# Object : 1
# Bytes Heap Memory: 3216
!MAGIC.embed = 1
o1 -> display,colorTable=5
o2 = obj_new('data',d2)
o2 -> display,colortable = 1
o1 -> getProperty, nchan = nchan, ngroups = ngroups
print,nchan,ngroups
40 20
help,/heap,/brief
Heap Variables:
# Pointer: 2
# Object : 2
# Bytes Heap Memory: 17632
抹除两个对象
obj_destroy,[o1,o2]
help,/heap,/brief
Heap Variables:
# Pointer: 0
# Object : 0
# Bytes Heap Memory: 0
一个类对象,至少应包括两部分:
- 自定义pro
- 初始化函数
function data::init,data device,decomposed = 0 loadct,0,/silent dsize = size(data) self.nchan = dsize[1] self.ngroups = dsize[2] self.dataPtr = ptr_new(data,/no_copy) self.colorTable = 0 self.winId = -1L return,1 end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; pro data__define define = { data, $
nchan:0, $
ngroups:0, $
winId:0L, $
colorTable:0, $
dataPtr:ptr_new() $
}
end
其中自定义pro为named struct,其中的元素(field)都可以用self引用
init函数初始化对象的参数,成功返回1,否则返回0
init和cleanup方法都成为lifecycle methods
## 继承(inheritance)
* base class
* derived class
例子:
>* SHAPE__DEFINE.PRO
* CIRCLE__DEFINE.PRO
* SQUARE__DEFINE.PRO
base class为`SHAPE__DEFINE.PRO`
>```
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro shape::cleanup
ptr_free,self.xPtr, self.yPtr
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function shape::init
self.xPtr = ptr_new(/allocate_heap)
self.yPtr = ptr_new(/allocate_heap)
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro shape__define
define = { shape, $
xPtr:ptr_new(), $
yPtr:ptr_new() $
}
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
derived class为CIRCLE__DEFINE.PRO
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; function circle::getArea return,!pi*self.radius^2 end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; function circle::draw plots,*self.xPtr,*self.yPtr,/device return,1 end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; function circle::init,xc = xc,yc = yc, radius = radius retVal =self -> shape::init() if retVal ne 1 then return,retVal if n_elements(xc) eq 0 then xc = 100.0 if n_elements(yc) eq 0 then yc = 100.0 if n_elements(radius) eq 0 then radius = 100.0 self.xc = xc self.yc = yc self.radius = radius nth = 100 th = (2.0*!pi/(nth-1.))*findgen(nth) *self.xPtr = xc + radius*cos(th) *self.yPtr = yc + radius*sin(th) return,1 end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; pro circle__define define = { circle, inherits SHAPE, $
radius:0.0, $
xc:0.0, $
yc:0.0 }
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
```idl
.compile -v 'C:\Users\luowei\Documents\dave_course_codes\intro_to_idl2_programs\programs\objects\shape__define.pro'
.compile -v 'C:\Users\luowei\Documents\dave_course_codes\intro_to_idl2_programs\programs\objects\circle__define.pro'
ocircle = obj_new('circle')
print,obj_class(ocircle)
CIRCLE
print,obj_class(ocircle,/superclass)
SHAPE
!MAGIC.embed = 1
ocircle -> draw()
1
print,ocircle->getArea()
31415.9
obj_destroy,ocircle
图形界面类对象
OBWID__DEFINE.PRO
.compile -v 'C:\Users\luowei\Documents\dave_course_codes\intro_to_idl2_programs\programs\objects\obwid__define.pro'
o = obj_new('obwid')
不点按钮,直接用函数来触发:
o -> genRand
o -> quit
检查是否所有指针和对象都销毁:
help,/heap,/brief
Heap Variables:
# Pointer: 0
# Object : 0
# Bytes Heap Memory: 0
上源代码:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; pro obWid::quit widget_control,self.tlb,/destroy end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; pro obWid::genRand rnd = randomn(s,1) strout = strtrim(string(rnd),2) widget_control,self.text,set_value = strout end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; pro obWidCleanup,tlb widget_control,tlb,get_uvalue = self obj_destroy,self end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; pro obWidEvents,event widget_control,event.id,get_uvalue = cmd call_method,cmd.method,cmd.object end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; function obWid::init ; Create the widgets self.tlb = widget_base(/col,title = 'First Object Widget') self.text = widget_text(self.tlb,value = '',xsize = 50) void = widget_button(self.tlb,value = 'Generate RND', $ uvalue = {object:self,method:'genRand'}) void = widget_button(self.tlb,value = 'QUIT', $ uvalue = {object:self,method:'quit'}) widget_control,self.tlb,/realize widget_control,self.tlb,set_uvalue = self xmanager,'obWid',self.tlb,event_handler = 'obWidEvents', $ /no_block,cleanup = 'obWidCleanup' return,1 end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; pro obWid__define define = { obWid, $ tlb:0L, $ text:0L $ } end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
!!in an object widget
program, a method cannot be called as an event handler
### A more complicated widget object with a command line interface
>COINTOSS__DEFINE.PRO
```idl
.compile -v 'C:\Users\luowei\Documents\dave_course_codes\intro_to_idl2_programs\programs\objects\cointoss__define.pro'
coin_example