OK using define-local-member-name works, see case 1 below, but it seems it would be much simpler if there was a form define/inheritable which made the method accessable within the class body where it was defined and in the sub-class bodies only. (see case 2 below) i.e. no wrapping in a let that returned multiple values etc.
Is there some reason there isn't such a form define/inheritable ? =================================== Case 1 (using define-local-member-name) ================================= #lang racket (define-values (fish% picky-fish%) (let () (define-local-member-name grow) (define fish% (class object% (init size) ; initialization argument (define current-size size) ; field (super-new) ; superclass initialization (define/public (get-size) current-size) (define/public (grow amt) (set! current-size (+ amt current-size))) (define/public (eat other-fish) (grow (send other-fish get-size))))) (define picky-fish% (class fish% (super-new) (define/override (grow amt) (super grow (* 3/4 amt))))) (values fish% picky-fish%))) (define joe-the-minnow (new fish% [size 2])) (define bud-the-minnow (new fish% [size 2])) (define big-al-the-pike (new fish% [size 10])) (define picky-selma (new picky-fish% [size 5])) (send picky-selma eat joe-the-minnow) (send picky-selma get-size) ;;this now correctly fails ;(send bud-the-minnow grow 5) ==================================== (Case 2 using a hypothetical define/inheritable) ==================================== #lang racket (define fish% (class object% (init size) (define current-size size) (super-new) (define/public (get-size) current-size) (define/public (grow amt) (set! current-size (+ amt current-size))) (define/inheritable (eat other-fish) ;;;hypothetical define/inheritable (grow (send other-fish get-size))))) (define picky-fish% (class fish% (super-new) (define/override (grow amt) (super grow (* 3/4 amt))))) (define joe-the-minnow (new fish% [size 2])) (define bud-the-minnow (new fish% [size 2])) (define big-al-the-pike (new fish% [size 10])) (define picky-selma (new picky-fish% [size 5])) (send picky-selma eat joe-the-minnow) (send picky-selma get-size) Thanks, Harry Spier On 1/3/13, Asumu Takikawa <as...@ccs.neu.edu> wrote: > On 2013-01-03 17:01:54 -0500, Harry Spier wrote: >> In Racket is it possible to override a non-public method? >> >> [...] >> >> Apologies if I've missed something obvious but I've just started going >> through the Classes and Objects documentation. I can see where you >> can declare a method public and overridable, or public and not >> overridable, but I don't see a declaration for a method to be private >> to the outside world but public and overridable to its sub-classes. > > You can use local member names to accomplish this. It effectively makes > certain method names lexically scoped. Here is an example: > > #lang racket > > (define-values (bomb% detonator%) > (let () > ;; lexically scoped method name > (define-local-member-name detonate) > (values > (class object% > (super-new) > ;; public only while the name is in scope > (define/public (detonate) > (displayln "boom!"))) > (class object% > (super-new) > (init-field bomb) > (define/public (trigger) > (send bomb detonate)))))) > > ;; error since `detonate` not in scope > ;(send (new bomb%) detonate) > > ;; works > (send (new detonator% [bomb (new bomb%)]) trigger) > > Using local member names, the "outside world" is wherever the name is > not bound. If it is in scope, you can invoke it, override it, etc and > your method declarations are done normally. > > Cheers, > Asumu > ____________________ Racket Users list: http://lists.racket-lang.org/users