DAVE的IDL教程(二)

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
output_5_0.png
o2 = obj_new('data',d2)
o2 -> display,colortable = 1
output_6_0.png
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

一个类对象,至少应包括两部分:

  1. 自定义pro
  2. 初始化函数
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')

idldave2_1.png

不点按钮,直接用函数来触发:

o -> genRand

idldave2_2.png

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


idldave2_3.png


推荐阅读更多精彩内容