2016-12-19 14 views
2

Допустим, у меня есть некоторый класс в Ракетка называется five%:Установка приватные поля другого экземпляра объекта одного и того же класса определяется в Ракетка

(define five% 
    (class object% 
    (super-new) 
    (define internal 5) 
    (define/public (get-number) 
     internal))) 

И скажем, я определил две пятерки:

(define f (new five%)) 
(define g (new five%)) 

Теперь как f, так и g имеют доступ к собственным internal. Но позвольте сказать, что я хочу добавить функцию к five%, называемому, скажем, change-other, который принимает еще один объект five% и изменяет его поле internal. Сказать что-то вроде этого:

(define/public (change-other other) 
    (set-field! internal other 4)) 

Теперь, очевидно, я не могу это сделать, потому что internal частное поле, и, следовательно, он не может получить доступ к любым другим экземплярам five%.

Итак, возможно ли в Racket создать класс с частным полем, к которому могут быть доступны только другие экземпляры этого класса?

ответ

2

Трюк состоит в том, чтобы сделать поле публичным, а затем использовать define-local-member-name, чтобы превратить его в личную.

Код будет выглядеть следующим образом:

(define five% 
    (let() 
    (define-local-member-name internal) 
    (class object% 
     (super-new) 
     (field [internal 5]) 
     (define/public (change-other other) 
     (set-field! internal other 4)) 
     (define/public (get-number) 
     internal)))) 

Линия (field [internal 5]) заменяет определение частного поля и создает публичный вариант.

Затем, в той же области действия класса, мы используем (define-local-member-name internal), чтобы превратить его в личное поле вне сферы действия класса.

Теперь мы можем создать два five% объекты:

(define f (new five%)) 
(define g (new five%)) 

И в РЕПЛ, мы видим, что g может мутировать f «s поле:

> (send g change-other f) 
> (send f get-number) 
4 

Но мы не можем сделать мутировать непосредственно :

> (get-field internal f) 
get-field: given object does not have the requested field 
    field name: internal 
    object: (object:five% ...) 

Благодаря Asumu за помощь в ответе.

 Смежные вопросы

  • Нет связанных вопросов^_^