28 创建右侧布局
先看代码,再作分析。
;创建右侧布局: (define (create-right-layout p) (let ([vp (new vertical-panel% [parent p] [style '(border)])]) (set! canvas/puzzle (new puzzle-canvas% [parent vp] [paint-callback (lambda (c dc) (draw-puzzle-picture dc))]))))
只要看完过前边的章节,对这个函数内容应该很清楚,就不再细说。
只是,这里出现了一个新的类——puzzle-canvas%——自定义的拼图画布类。接下来就进入一个新的天地——探讨如何用Racket创建一个新的类,这个类是拼图的重头戏,之前所有对图片所作的操作就为了通过这个类来展示。
28.1 类
类(class)表达式表示一个类的值,就像一个 lambda 表达式一样:
(class superclass-expr decl-or-expr ...)
superclass-expr 为新类的基类。 每个 decl-or-expr 既是一个声明,关系到对方法、字段和初始化参数;也是一个表达式,每次求值就实例化类。 换句话说,与方法之类的构造器不同,类具有与字段和方法声明交错的初始化表达式。
按照惯例,类名以 % 结束。内置根类是 object%。
比如创建一个类:
;拼图画布类: (define puzzle-canvas% (class canvas% (super-new)))
这里新创建的类puzzle-canvas%的基类为canvas%,在创建类的时候同时用(super-new)初始化基类。这样就创建了一个新的类,其功能现在与canvas%一致,后边可以通过进一步添加类字段或成员函数来对其进行扩展。
类的完整定义如下:
(class* superclass-expr (interface-expr ...) class-clause ...) class-clause = (inspect inspector-expr) | (init init-decl ...) | (init-field init-decl ...) | (field field-decl ...) | (inherit-field maybe-renamed ...) | (init-rest id) | (init-rest) | (public maybe-renamed ...) | (pubment maybe-renamed ...) | (public-final maybe-renamed ...) | (override maybe-renamed ...) | (overment maybe-renamed ...) | (override-final maybe-renamed ...) | (augment maybe-renamed ...) | (augride maybe-renamed ...) | (augment-final maybe-renamed ...) | (private id ...) | (abstract id ...) | (inherit maybe-renamed ...)