365 lines
No EOL
316 KiB
HTML
365 lines
No EOL
316 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"/><meta name="viewport" content="width=device-width, initial-scale=0.8"/><title>13 Classes and Objects</title><link rel="stylesheet" type="text/css" href="../scribble.css" title="default"/><link rel="stylesheet" type="text/css" href="../racket.css" title="default"/><link rel="stylesheet" type="text/css" href="../manual-style.css" title="default"/><link rel="stylesheet" type="text/css" href="../manual-racket.css" title="default"/><link rel="stylesheet" type="text/css" href="../manual-racket.css" title="default"/><link rel="stylesheet" type="text/css" href="../doc-site.css" title="default"/><script type="text/javascript" src="../scribble-common.js"></script><script type="text/javascript" src="../manual-racket.js"></script><script type="text/javascript" src="../manual-racket.js"></script><script type="text/javascript" src="../doc-site.js"></script><script type="text/javascript" src="../local-redirect/local-redirect.js"></script><script type="text/javascript" src="../local-redirect/local-user-redirect.js"></script><!--[if IE 6]><style type="text/css">.SIEHidden { overflow: hidden; }</style><![endif]--></head><body id="doc-racket-lang-org"><div class="tocset"><div class="tocview"><div class="tocviewlist tocviewlisttopspace"><div class="tocviewtitle"><table cellspacing="0" cellpadding="0"><tr><td style="width: 1em;"><a href="javascript:void(0);" title="Expand/Collapse" class="tocviewtoggle" onclick="TocviewToggle(this,"tocview_0");">▼</a></td><td></td><td><a href="index.html" class="tocviewlink" data-pltdoc="x">The Racket Guide</a></td></tr></table></div><div class="tocviewsublisttop" style="display: block;" id="tocview_0"><table cellspacing="0" cellpadding="0"><tr><td align="right">1 </td><td><a href="intro.html" class="tocviewlink" data-pltdoc="x">Welcome to Racket</a></td></tr><tr><td align="right">2 </td><td><a href="to-scheme.html" class="tocviewlink" data-pltdoc="x">Racket Essentials</a></td></tr><tr><td align="right">3 </td><td><a href="datatypes.html" class="tocviewlink" data-pltdoc="x">Built-<wbr></wbr>In Datatypes</a></td></tr><tr><td align="right">4 </td><td><a href="scheme-forms.html" class="tocviewlink" data-pltdoc="x">Expressions and Definitions</a></td></tr><tr><td align="right">5 </td><td><a href="define-struct.html" class="tocviewlink" data-pltdoc="x">Programmer-<wbr></wbr>Defined Datatypes</a></td></tr><tr><td align="right">6 </td><td><a href="modules.html" class="tocviewlink" data-pltdoc="x">Modules</a></td></tr><tr><td align="right">7 </td><td><a href="contracts.html" class="tocviewlink" data-pltdoc="x">Contracts</a></td></tr><tr><td align="right">8 </td><td><a href="i_o.html" class="tocviewlink" data-pltdoc="x">Input and Output</a></td></tr><tr><td align="right">9 </td><td><a href="regexp.html" class="tocviewlink" data-pltdoc="x">Regular Expressions</a></td></tr><tr><td align="right">10 </td><td><a href="control.html" class="tocviewlink" data-pltdoc="x">Exceptions and Control</a></td></tr><tr><td align="right">11 </td><td><a href="for.html" class="tocviewlink" data-pltdoc="x">Iterations and Comprehensions</a></td></tr><tr><td align="right">12 </td><td><a href="match.html" class="tocviewlink" data-pltdoc="x">Pattern Matching</a></td></tr><tr><td align="right">13 </td><td><a href="classes.html" class="tocviewselflink" data-pltdoc="x">Classes and Objects</a></td></tr><tr><td align="right">14 </td><td><a href="units.html" class="tocviewlink" data-pltdoc="x">Units</a></td></tr><tr><td align="right">15 </td><td><a href="reflection.html" class="tocviewlink" data-pltdoc="x">Reflection and Dynamic Evaluation</a></td></tr><tr><td align="right">16 </td><td><a href="macros.html" class="tocviewlink" data-pltdoc="x">Macros</a></td></tr><tr><td align="right">17 </td><td><a href="languages.html" class="tocviewlink" data-pltdoc="x">Creating Languages</a></td></tr><tr><td align="right">18 </td><td><a href="concurrency.html" class="tocviewlink" data-pltdoc="x">Concurrency and Synchronization</a></td></tr><tr><td align="right">19 </td><td><a href="performance.html" class="tocviewlink" data-pltdoc="x">Performance</a></td></tr><tr><td align="right">20 </td><td><a href="parallelism.html" class="tocviewlink" data-pltdoc="x">Parallelism</a></td></tr><tr><td align="right">21 </td><td><a href="running.html" class="tocviewlink" data-pltdoc="x">Running and Creating Executables</a></td></tr><tr><td align="right">22 </td><td><a href="More_Libraries.html" class="tocviewlink" data-pltdoc="x">More Libraries</a></td></tr><tr><td align="right">23 </td><td><a href="dialects.html" class="tocviewlink" data-pltdoc="x">Dialects of Racket and Scheme</a></td></tr><tr><td align="right">24 </td><td><a href="other-editors.html" class="tocviewlink" data-pltdoc="x">Command-<wbr></wbr>Line Tools and Your Editor of Choice</a></td></tr><tr><td align="right"></td><td><a href="doc-bibliography.html" class="tocviewlink" data-pltdoc="x">Bibliography</a></td></tr><tr><td align="right"></td><td><a href="doc-index.html" class="tocviewlink" data-pltdoc="x">Index</a></td></tr></table></div></div><div class="tocviewlist"><table cellspacing="0" cellpadding="0"><tr><td style="width: 1em;"><a href="javascript:void(0);" title="Expand/Collapse" class="tocviewtoggle" onclick="TocviewToggle(this,"tocview_1");">►</a></td><td>13 </td><td><a href="classes.html" class="tocviewselflink" data-pltdoc="x">Classes and Objects</a></td></tr></table><div class="tocviewsublistbottom" style="display: none;" id="tocview_1"><table cellspacing="0" cellpadding="0"><tr><td align="right">13.1 </td><td><a href="classes.html#%28part._methods%29" class="tocviewlink" data-pltdoc="x">Methods</a></td></tr><tr><td align="right">13.2 </td><td><a href="classes.html#%28part._initargs%29" class="tocviewlink" data-pltdoc="x">Initialization Arguments</a></td></tr><tr><td align="right">13.3 </td><td><a href="classes.html#%28part._intnames%29" class="tocviewlink" data-pltdoc="x">Internal and External Names</a></td></tr><tr><td align="right">13.4 </td><td><a href="classes.html#%28part._.Interfaces%29" class="tocviewlink" data-pltdoc="x">Interfaces</a></td></tr><tr><td align="right">13.5 </td><td><a href="classes.html#%28part._inner%29" class="tocviewlink" data-pltdoc="x">Final, Augment, and Inner</a></td></tr><tr><td align="right">13.6 </td><td><a href="classes.html#%28part._extnames%29" class="tocviewlink" data-pltdoc="x">Controlling the Scope of External Names</a></td></tr><tr><td align="right">13.7 </td><td><a href="classes.html#%28part._.Mixins%29" class="tocviewlink" data-pltdoc="x">Mixins</a></td></tr><tr><td align="right">13.8 </td><td><a href="classes.html#%28part._.Traits%29" class="tocviewlink" data-pltdoc="x">Traits</a></td></tr><tr><td align="right">13.9 </td><td><a href="classes.html#%28part._.Class_.Contracts%29" class="tocviewlink" data-pltdoc="x">Class Contracts</a></td></tr></table></div></div></div><div class="tocsub"><div class="tocsubtitle">On this page:</div><table class="tocsublist" cellspacing="0"><tr><td><span class="tocsublinknumber">13.1<tt> </tt></span><a href="classes.html#%28part._methods%29" class="tocsubseclink" data-pltdoc="x">Methods</a></td></tr><tr><td><span class="tocsublinknumber">13.2<tt> </tt></span><a href="classes.html#%28part._initargs%29" class="tocsubseclink" data-pltdoc="x">Initialization Arguments</a></td></tr><tr><td><span class="tocsublinknumber">13.3<tt> </tt></span><a href="classes.html#%28part._intnames%29" class="tocsubseclink" data-pltdoc="x">Internal and External Names</a></td></tr><tr><td><span class="tocsublinknumber">13.4<tt> </tt></span><a href="classes.html#%28part._.Interfaces%29" class="tocsubseclink" data-pltdoc="x">Interfaces</a></td></tr><tr><td><span class="tocsublinknumber">13.5<tt> </tt></span><a href="classes.html#%28part._inner%29" class="tocsubseclink" data-pltdoc="x">Final, Augment, and Inner</a></td></tr><tr><td><span class="tocsublinknumber">13.6<tt> </tt></span><a href="classes.html#%28part._extnames%29" class="tocsubseclink" data-pltdoc="x">Controlling the Scope of External Names</a></td></tr><tr><td><span class="tocsublinknumber">13.7<tt> </tt></span><a href="classes.html#%28part._.Mixins%29" class="tocsubseclink" data-pltdoc="x">Mixins</a></td></tr><tr><td><span class="tocsublinknumber">13.7.1<tt> </tt></span><a href="classes.html#%28part._.Mixins_and_.Interfaces%29" class="tocsubseclink" data-pltdoc="x">Mixins and Interfaces</a></td></tr><tr><td><span class="tocsublinknumber">13.7.2<tt> </tt></span><a href="classes.html#%28part._.The_mixin_.Form%29" class="tocsubseclink" data-pltdoc="x">The <span class="RktSym"><span class="RktStxLink">mixin</span></span> Form</a></td></tr><tr><td><span class="tocsublinknumber">13.7.3<tt> </tt></span><a href="classes.html#%28part._parammixins%29" class="tocsubseclink" data-pltdoc="x">Parameterized Mixins</a></td></tr><tr><td><span class="tocsublinknumber">13.8<tt> </tt></span><a href="classes.html#%28part._.Traits%29" class="tocsubseclink" data-pltdoc="x">Traits</a></td></tr><tr><td><span class="tocsublinknumber">13.8.1<tt> </tt></span><a href="classes.html#%28part._.Traits_as_.Sets_of_.Mixins%29" class="tocsubseclink" data-pltdoc="x">Traits as Sets of Mixins</a></td></tr><tr><td><span class="tocsublinknumber">13.8.2<tt> </tt></span><a href="classes.html#%28part._.Inherit_and_.Super_in_.Traits%29" class="tocsubseclink" data-pltdoc="x">Inherit and Super in Traits</a></td></tr><tr><td><span class="tocsublinknumber">13.8.3<tt> </tt></span><a href="classes.html#%28part._.The_trait_.Form%29" class="tocsubseclink" data-pltdoc="x">The <span class="RktSym"><span class="RktStxLink">trait</span></span> Form</a></td></tr><tr><td><span class="tocsublinknumber">13.9<tt> </tt></span><a href="classes.html#%28part._.Class_.Contracts%29" class="tocsubseclink" data-pltdoc="x">Class Contracts</a></td></tr><tr><td><span class="tocsublinknumber">13.9.1<tt> </tt></span><a href="classes.html#%28part._.External_.Class_.Contracts%29" class="tocsubseclink" data-pltdoc="x">External Class Contracts</a></td></tr><tr><td><span class="tocsublinknumber">13.9.2<tt> </tt></span><a href="classes.html#%28part._.Internal_.Class_.Contracts%29" class="tocsubseclink" data-pltdoc="x">Internal Class Contracts</a></td></tr></table></div></div><div class="maincolumn"><div class="main"><div class="navsettop"><span class="navleft"><form class="searchform"><input class="searchbox" id="searchbox" type="text" tabindex="1" placeholder="...search manuals..." title="Enter a search string to search the manuals" onkeypress="return DoSearchKey(event, this, "8.6", "../");"/></form> <a href="https://download.racket-lang.org/releases/8.6/doc/index.html" title="up to the documentation top" data-pltdoc="x" onclick="return GotoPLTRoot("8.6");">top</a><span class="tocsettoggle"> <a href="javascript:void(0);" title="show/hide table of contents" onclick="TocsetToggle();">contents</a></span></span><span class="navright"> <a href="match.html" title="backward to "12 Pattern Matching"" data-pltdoc="x">← prev</a> <a href="index.html" title="up to "The Racket Guide"" data-pltdoc="x">up</a> <a href="units.html" title="forward to "14 Units (Components)"" data-pltdoc="x">next →</a></span> </div><h3 x-source-module="(lib "scribblings/guide/guide.scrbl")" x-source-pkg="racket-doc" x-part-tag=""classes"">13<tt> </tt><a name="(part._classes)"></a>Classes and Objects</h3><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p>This chapter is based on a paper [<a href="doc-bibliography.html#%28cite._.Flatt06%29" data-pltdoc="x">Flatt06</a>].</p></blockquote></blockquote></blockquote><p>A <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span> expression denotes a first-class value,
|
|
just like a <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=lambda.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._lambda%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">lambda</a></span> expression:</p><blockquote class="leftindent"><blockquote class="SVInsetFlow"><table cellspacing="0" cellpadding="0" class="boxed RBoxed"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span><span class="hspace"> </span><span class="RktVar">superclass-expr</span><span class="hspace"> </span><span class="RktVar">decl-or-expr</span><span class="hspace"> </span><span class="RktMeta">...</span><span class="RktPn">)</span></td></tr></table></blockquote></blockquote><p>The <span class="RktVar">superclass-expr</span> determines the superclass for the new
|
|
class. Each <span class="RktVar">decl-or-expr</span> is either a declaration related to
|
|
methods, fields, and initialization arguments, or it is an expression
|
|
that is evaluated each time that the class is instantiated. In other
|
|
words, instead of a method-like constructor, a class has
|
|
initialization expressions interleaved with field and method
|
|
declarations.</p><p>By convention, class names end with <span class="RktSym">%</span>. The built-in root class is
|
|
<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528def._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._object%7E25%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">object%</a></span>. The following expression creates a class with
|
|
public methods <span class="RktSym">get-size</span>, <span class="RktSym">grow</span>, and <span class="RktSym">eat</span>:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528def._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._object%7E25%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">object%</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._init%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">init</a></span><span class="hspace"> </span><span class="RktSym">size</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">initialization argument</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">current-size</span><span class="hspace"> </span><span class="RktSym">size</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">field</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._super-new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">super-new</a></span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">superclass initialization</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Fpublic%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/public</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">get-size</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">current-size</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Fpublic%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/public</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">grow</span><span class="hspace"> </span><span class="RktSym">amt</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=set_.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._set%2521%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">set!</a></span><span class="hspace"> </span><span class="RktSym">current-size</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=generic-numbers.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._%252B%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktSym">amt</span><span class="hspace"> </span><span class="RktSym">current-size</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Fpublic%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/public</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">eat</span><span class="hspace"> </span><span class="RktSym">other-fish</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">grow</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._send%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">send</a></span><span class="hspace"> </span><span class="RktSym">other-fish</span><span class="hspace"> </span><span class="RktSym">get-size</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p>The <span class="RktSym">size</span> initialization argument must be supplied via a named
|
|
argument when instantiating the class through the <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">new</a></span> form:</p><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">new</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528def._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._object%7E25%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">object%</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._init%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">init</a></span><span class="hspace"> </span><span class="RktSym">size</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">....</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">size</span><span class="hspace"> </span><span class="RktVal">10</span><span class="RktPn">]</span><span class="RktPn">)</span></p></blockquote><p>Of course, we can also name the class and its instance:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">fish%</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528def._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._object%7E25%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">object%</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._init%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">init</a></span><span class="hspace"> </span><span class="RktSym">size</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">....</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">charlie</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">new</a></span><span class="hspace"> </span><span class="RktSym">fish%</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">size</span><span class="hspace"> </span><span class="RktVal">10</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p>In the definition of <span class="RktSym">fish%</span>, <span class="RktSym">current-size</span> is a
|
|
private field that starts out with the value of the <span class="RktSym">size</span>
|
|
initialization argument. Initialization arguments like <span class="RktSym">size</span>
|
|
are available only during class instantiation, so they cannot be
|
|
referenced directly from a method. The <span class="RktSym">current-size</span> field, in
|
|
contrast, is available to methods.</p><p>The <span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._super-new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">super-new</a></span><span class="RktPn">)</span> expression in <span class="RktSym">fish%</span> invokes the
|
|
initialization of the superclass. In this case, the superclass is
|
|
<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528def._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._object%7E25%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">object%</a></span>, which takes no initialization arguments and performs
|
|
no work; <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._super-new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">super-new</a></span> must be used, anyway, because a class must
|
|
always invoke its superclass’s initialization.</p><p>Initialization arguments, field declarations, and expressions such as
|
|
<span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._super-new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">super-new</a></span><span class="RktPn">)</span> can appear in any order within a <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span>,
|
|
and they can be interleaved with method declarations. The relative
|
|
order of expressions in the class determines the order of evaluation
|
|
during instantiation. For example, if a field’s initial value requires
|
|
calling a method that works only after superclass initialization, then
|
|
the field declaration must be placed after the <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._super-new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">super-new</a></span>
|
|
call. Ordering field and initialization declarations in this way helps
|
|
avoid imperative assignment. The relative order of method declarations
|
|
makes no difference for evaluation, because methods are fully defined
|
|
before a class is instantiated.</p><h4 x-source-module="(lib "scribblings/guide/guide.scrbl")" x-source-pkg="racket-doc" x-part-tag=""methods"">13.1<tt> </tt><a name="(part._methods)"></a>Methods</h4><p>Each of the three <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Fpublic%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/public</a></span> declarations in
|
|
<span class="RktSym">fish%</span> introduces a new method. The declaration uses the same
|
|
syntax as a Racket function, but a method is not accessible as an
|
|
independent function. A call to the <span class="RktSym">grow</span> method of a
|
|
<span class="RktSym">fish%</span> object requires the <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._send%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">send</a></span> form:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._send%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">send</a></span><span class="hspace"> </span><span class="RktSym">charlie</span><span class="hspace"> </span><span class="RktSym">grow</span><span class="hspace"> </span><span class="RktVal">6</span><span class="RktPn">)</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._send%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">send</a></span><span class="hspace"> </span><span class="RktSym">charlie</span><span class="hspace"> </span><span class="RktSym">get-size</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">16</span></p></td></tr></table></blockquote><p>Within <span class="RktSym">fish%</span>, self methods can be called like functions,
|
|
because the method names are in scope. For example, the <span class="RktSym">eat</span>
|
|
method within <span class="RktSym">fish%</span> directly invokes the <span class="RktSym">grow</span>
|
|
method. Within a class, attempting to use a method name in any way
|
|
other than a method call results in a syntax error.</p><p>In some cases, a class must call methods that are supplied by the superclass
|
|
but not overridden. In that case, the class can use <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._send%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">send</a></span>
|
|
with <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._this%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">this</a></span> to access the method:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0"><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">hungry-fish%</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span><span class="hspace"> </span><span class="RktSym">fish%</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._super-new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">super-new</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Fpublic%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/public</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">eat-more</span><span class="hspace"> </span><span class="RktSym">fish1</span><span class="hspace"> </span><span class="RktSym">fish2</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._send%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">send</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._this%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">this</a></span><span class="hspace"> </span><span class="RktSym">eat</span><span class="hspace"> </span><span class="RktSym">fish1</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._send%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">send</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._this%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">this</a></span><span class="hspace"> </span><span class="RktSym">eat</span><span class="hspace"> </span><span class="RktSym">fish2</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><p> </p></td></tr><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td></td></tr></table></td></tr></table></blockquote><p>Alternately, the class can declare the existence of a method using <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._inherit%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">inherit</a></span>,
|
|
which brings the method name into scope for a direct call:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0"><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">hungry-fish%</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span><span class="hspace"> </span><span class="RktSym">fish%</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._super-new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">super-new</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._inherit%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">inherit</a></span><span class="hspace"> </span><span class="RktSym">eat</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Fpublic%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/public</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">eat-more</span><span class="hspace"> </span><span class="RktSym">fish1</span><span class="hspace"> </span><span class="RktSym">fish2</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">eat</span><span class="hspace"> </span><span class="RktSym">fish1</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">eat</span><span class="hspace"> </span><span class="RktSym">fish2</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><p> </p></td></tr><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td></td></tr></table></td></tr></table></blockquote><p>With the <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._inherit%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">inherit</a></span> declaration, if <span class="RktSym">fish%</span> had not
|
|
provided an <span class="RktSym">eat</span> method, an error would be signaled in the
|
|
evaluation of the <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span> form for <span class="RktSym">hungry-fish%</span>. In
|
|
contrast, with <span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._send%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">send</a></span><span class="stt"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._this%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">this</a></span><span class="stt"> </span><span class="RktSym">....</span><span class="RktPn">)</span>, an error would not be
|
|
signaled until the <span class="RktSym">eat-more</span> method is called and the
|
|
<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._send%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">send</a></span> form is evaluated. For this reason, <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._inherit%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">inherit</a></span> is
|
|
preferred.</p><p>Another drawback of <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._send%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">send</a></span> is that it is less efficient than
|
|
<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._inherit%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">inherit</a></span>. Invocation of a method via <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._send%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">send</a></span> involves
|
|
finding a method in the target object’s class at run time, making
|
|
<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._send%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">send</a></span> comparable to an interface-based method call in Java. In
|
|
contrast, <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._inherit%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">inherit</a></span>-based method invocations use an offset
|
|
within the class’s method table that is computed when the class is
|
|
created.</p><p>To achieve performance similar to <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._inherit%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">inherit</a></span>-based method calls when
|
|
invoking a method from outside the method’s class, the programmer must use the
|
|
<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._generic%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">generic</a></span> form, which produces a class- and method-specific
|
|
<span style="font-style: italic">generic method</span> to be invoked with <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._send-generic%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">send-generic</a></span>:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">get-fish-size</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._generic%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">generic</a></span><span class="hspace"> </span><span class="RktSym">fish%</span><span class="hspace"> </span><span class="RktSym">get-size</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><p> </p></td></tr><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._send-generic%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">send-generic</a></span><span class="hspace"> </span><span class="RktSym">charlie</span><span class="hspace"> </span><span class="RktSym">get-fish-size</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">16</span></p></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._send-generic%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">send-generic</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">new</a></span><span class="hspace"> </span><span class="RktSym">hungry-fish%</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">size</span><span class="hspace"> </span><span class="RktVal">32</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">get-fish-size</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">32</span></p></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._send-generic%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">send-generic</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">new</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528def._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._object%7E25%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">object%</a></span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">get-fish-size</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktErr">generic:get-size: target is not an instance of the generic's</span></p></td></tr><tr><td><p><span class="RktErr">class</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">target: (object)</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">class name: fish%</span></p></td></tr></table></td></tr></table></blockquote><p>Roughly speaking, the form translates the class and the external
|
|
method name to a location in the class’s method table. As illustrated
|
|
by the last example, sending through a generic method checks that its
|
|
argument is an instance of the generic’s class.</p><p>Whether a method is called directly within a <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span>,
|
|
through a generic method,
|
|
or through <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._send%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">send</a></span>, method overriding works in the usual way:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0"><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">picky-fish%</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span><span class="hspace"> </span><span class="RktSym">fish%</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._super-new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">super-new</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Foverride%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/override</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">grow</span><span class="hspace"> </span><span class="RktSym">amt</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._super%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">super</a></span><span class="hspace"> </span><span class="RktSym">grow</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=generic-numbers.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._%252A%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">*</a></span><span class="hspace"> </span><span class="RktVal">3/4</span><span class="hspace"> </span><span class="RktSym">amt</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">daisy</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">new</a></span><span class="hspace"> </span><span class="RktSym">picky-fish%</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">size</span><span class="hspace"> </span><span class="RktVal">20</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><p> </p></td></tr><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._send%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">send</a></span><span class="hspace"> </span><span class="RktSym">daisy</span><span class="hspace"> </span><span class="RktSym">eat</span><span class="hspace"> </span><span class="RktSym">charlie</span><span class="RktPn">)</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._send%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">send</a></span><span class="hspace"> </span><span class="RktSym">daisy</span><span class="hspace"> </span><span class="RktSym">get-size</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">32</span></p></td></tr></table></td></tr></table></blockquote><p>The <span class="RktSym">grow</span> method in <span class="RktSym">picky-fish%</span> is declared with
|
|
<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Foverride%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/override</a></span> instead of <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Fpublic%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/public</a></span>, because
|
|
<span class="RktSym">grow</span> is meant as an overriding declaration. If <span class="RktSym">grow</span>
|
|
had been declared with <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Fpublic%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/public</a></span>, an error would have
|
|
been signaled when evaluating the <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span> expression, because
|
|
<span class="RktSym">fish%</span> already supplies <span class="RktSym">grow</span>.</p><p>Using <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Foverride%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/override</a></span> also allows the invocation of the
|
|
overridden method via a <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._super%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">super</a></span> call. For example, the
|
|
<span class="RktSym">grow</span> implementation in <span class="RktSym">picky-fish%</span> uses
|
|
<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._super%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">super</a></span> to delegate to the superclass implementation.</p><h4 x-source-module="(lib "scribblings/guide/guide.scrbl")" x-source-pkg="racket-doc" x-part-tag=""initargs"">13.2<tt> </tt><a name="(part._initargs)"></a>Initialization Arguments</h4><p>Since <span class="RktSym">picky-fish%</span> declares no initialization arguments, any
|
|
initialization values supplied in <span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">new</a></span><span class="stt"> </span><span class="RktSym">picky-fish%</span><span class="stt"> </span><span class="RktSym">....</span><span class="RktPn">)</span> are
|
|
propagated to the superclass initialization, i.e., to <span class="RktSym">fish%</span>.
|
|
A subclass can supply additional initialization arguments for its
|
|
superclass in a <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._super-new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">super-new</a></span> call, and such initialization
|
|
arguments take precedence over arguments supplied to <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">new</a></span>. For
|
|
example, the following <span class="RktSym">size-10-fish%</span> class always generates
|
|
fish of size 10:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">size-10-fish%</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span><span class="hspace"> </span><span class="RktSym">fish%</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._super-new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">super-new</a></span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">size</span><span class="hspace"> </span><span class="RktVal">10</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><p> </p></td></tr><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._send%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">send</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">new</a></span><span class="hspace"> </span><span class="RktSym">size-10-fish%</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">get-size</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">10</span></p></td></tr></table></td></tr></table></blockquote><p>In the case of <span class="RktSym">size-10-fish%</span>, supplying a <span class="RktSym">size</span>
|
|
initialization argument with <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">new</a></span> would result in an
|
|
initialization error; because the <span class="RktSym">size</span> in <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._super-new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">super-new</a></span>
|
|
takes precedence, a <span class="RktSym">size</span> supplied to <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">new</a></span> would have
|
|
no target declaration.</p><p>An initialization argument is optional if the <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span> form
|
|
declares a default value. For example, the following <span class="RktSym">default-10-fish%</span>
|
|
class accepts a <span class="RktSym">size</span> initialization argument, but its value defaults to
|
|
10 if no value is supplied on instantiation:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0"><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">default-10-fish%</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span><span class="hspace"> </span><span class="RktSym">fish%</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._init%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">init</a></span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">size</span><span class="hspace"> </span><span class="RktVal">10</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._super-new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">super-new</a></span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">size</span><span class="hspace"> </span><span class="RktSym">size</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><p> </p></td></tr><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">new</a></span><span class="hspace"> </span><span class="RktSym">default-10-fish%</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">(object:default-10-fish% ...)</span></p></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">new</a></span><span class="hspace"> </span><span class="RktSym">default-10-fish%</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">size</span><span class="hspace"> </span><span class="RktVal">20</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">(object:default-10-fish% ...)</span></p></td></tr></table></td></tr></table></blockquote><p>In this example, the <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._super-new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">super-new</a></span> call propagates its own
|
|
<span class="RktSym">size</span> value as the <span class="RktSym">size</span> initialization argument to
|
|
the superclass.</p><h4 x-source-module="(lib "scribblings/guide/guide.scrbl")" x-source-pkg="racket-doc" x-part-tag=""intnames"">13.3<tt> </tt><a name="(part._intnames)"></a>Internal and External Names</h4><p>The two uses of <span class="RktSym">size</span> in <span class="RktSym">default-10-fish%</span> expose the
|
|
double life of class-member identifiers. When <span class="RktSym">size</span> is the
|
|
first identifier of a bracketed pair in <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">new</a></span> or
|
|
<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._super-new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">super-new</a></span>, <span class="RktSym">size</span> is an <span style="font-style: italic">external name</span> that
|
|
is symbolically matched to an initialization argument in a class. When
|
|
<span class="RktSym">size</span> appears as an expression within
|
|
<span class="RktSym">default-10-fish%</span>, <span class="RktSym">size</span> is an <span style="font-style: italic">internal name</span>
|
|
that is lexically scoped. Similarly, a call to an inherited
|
|
<span class="RktSym">eat</span> method uses <span class="RktSym">eat</span> as an internal name, whereas a
|
|
<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._send%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">send</a></span> of <span class="RktSym">eat</span> uses <span class="RktSym">eat</span> as an external name.</p><p>The full syntax of the <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span> form allows a programmer to
|
|
specify distinct internal and external names for a class member. Since
|
|
internal names are local, they can be renamed to avoid shadowing or
|
|
conflicts. Such renaming is not frequently necessary, but workarounds
|
|
in the absence of renaming can be especially cumbersome.</p><h4 x-source-module="(lib "scribblings/guide/guide.scrbl")" x-source-pkg="racket-doc" x-part-tag=""Interfaces"">13.4<tt> </tt><a name="(part._.Interfaces)"></a>Interfaces</h4><p>Interfaces are useful for checking that an object or a class
|
|
implements a set of methods with a particular (implied) behavior.
|
|
This use of interfaces is helpful even without a static type system
|
|
(which is the main reason that Java has interfaces).</p><p>An interface in Racket is created using the <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createinterface.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._interface%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">interface</a></span>
|
|
form, which merely declares the method names required to implement the
|
|
interface. An interface can extend other interfaces, which means that
|
|
implementations of the interface automatically implement the extended
|
|
interfaces.</p><blockquote class="leftindent"><blockquote class="SVInsetFlow"><table cellspacing="0" cellpadding="0" class="boxed RBoxed"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createinterface.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._interface%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">interface</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktVar">superinterface-expr</span><span class="hspace"> </span><span class="RktMeta">...</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVar">id</span><span class="hspace"> </span><span class="RktMeta">...</span><span class="RktPn">)</span></td></tr></table></blockquote></blockquote><p>To declare that a class implements an interface, the
|
|
<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%252A%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class*</a></span> form must be used instead of <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span>:</p><blockquote class="leftindent"><blockquote class="SVInsetFlow"><table cellspacing="0" cellpadding="0" class="boxed RBoxed"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%252A%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class*</a></span><span class="hspace"> </span><span class="RktVar">superclass-expr</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktVar">interface-expr</span><span class="hspace"> </span><span class="RktMeta">...</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVar">decl-or-expr</span><span class="hspace"> </span><span class="RktMeta">...</span><span class="RktPn">)</span></td></tr></table></blockquote></blockquote><p>For example, instead of forcing all fish classes to be derived from
|
|
<span class="RktSym">fish%</span>, we can define <span class="RktSym">fish-interface</span> and change the
|
|
<span class="RktSym">fish%</span> class to declare that it implements
|
|
<span class="RktSym">fish-interface</span>:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">fish-interface</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createinterface.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._interface%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">interface</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">get-size</span><span class="hspace"> </span><span class="RktSym">grow</span><span class="hspace"> </span><span class="RktSym">eat</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">fish%</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%252A%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class*</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528def._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._object%7E25%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">object%</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">fish-interface</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">....</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p>If the definition of <span class="RktSym">fish%</span> does not include
|
|
<span class="RktSym">get-size</span>, <span class="RktSym">grow</span>, and <span class="RktSym">eat</span> methods, then an
|
|
error is signaled in the evaluation of the <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%252A%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class*</a></span> form,
|
|
because implementing the <span class="RktSym">fish-interface</span> interface requires
|
|
those methods.</p><p>The <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objectutils.html%23%2528def._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._is-a%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">is-a?</a></span> predicate accepts an object as its first argument
|
|
and either a class or interface as its second argument. When given a
|
|
class, <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objectutils.html%23%2528def._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._is-a%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">is-a?</a></span> checks whether the object is an instance of that
|
|
class or a derived class. When given an interface, <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objectutils.html%23%2528def._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._is-a%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">is-a?</a></span>
|
|
checks whether the object’s class implements the interface. In
|
|
addition, the <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objectutils.html%23%2528def._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._implementation%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">implementation?</a></span> predicate checks whether a
|
|
given class implements a given interface.</p><h4 x-source-module="(lib "scribblings/guide/guide.scrbl")" x-source-pkg="racket-doc" x-part-tag=""inner"">13.5<tt> </tt><a name="(part._inner)"></a>Final, Augment, and Inner</h4><p>As in Java, a method in a <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span> form can be specified as
|
|
<span style="font-style: italic">final</span>, which means that a subclass cannot override the
|
|
method. A final method is declared using <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._public-final%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">public-final</a></span> or
|
|
<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._override-final%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">override-final</a></span>, depending on whether the declaration is for a
|
|
new method or an overriding implementation.</p><p>Between the extremes of allowing arbitrary overriding and disallowing
|
|
overriding entirely, the class system also supports Beta-style
|
|
<span style="font-style: italic">augmentable</span> methods [<a href="doc-bibliography.html#%28cite._.Goldberg04%29" data-pltdoc="x">Goldberg04</a>]. A method
|
|
declared with <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._pubment%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">pubment</a></span> is like <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._public%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">public</a></span>, but the method
|
|
cannot be overridden in subclasses; it can be augmented only. A
|
|
<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._pubment%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">pubment</a></span> method must explicitly invoke an augmentation (if any)
|
|
using <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._inner%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">inner</a></span>; a subclass augments the method using
|
|
<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._augment%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">augment</a></span>, instead of <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._override%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">override</a></span>.</p><p>In general, a method can switch between augment and override modes in
|
|
a class derivation. The <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._augride%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">augride</a></span> method specification
|
|
indicates an augmentation to a method where the augmentation is itself
|
|
overrideable in subclasses (though the superclass’s implementation
|
|
cannot be overridden). Similarly, <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._overment%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">overment</a></span> overrides a method
|
|
and makes the overriding implementation augmentable.</p><h4 x-source-module="(lib "scribblings/guide/guide.scrbl")" x-source-pkg="racket-doc" x-part-tag=""extnames"">13.6<tt> </tt><a name="(part._extnames)"></a>Controlling the Scope of External Names</h4><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p>Java’s access modifiers (like <a name="(idx._(gentag._4._(lib._scribblings/guide/guide..scrbl)))"></a><span class="stt">protected</span>)
|
|
play a role similar to <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define-member-name%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define-member-name</a></span>, but
|
|
unlike in Java, Racket’s mechanism for controlling access
|
|
is based on lexical scope, not the inheritance hierarchy.</p></blockquote></blockquote></blockquote><p>As noted in <a href="classes.html#%28part._intnames%29" data-pltdoc="x">Internal and External Names</a>, class members have both
|
|
internal and external names. A member definition binds an internal
|
|
name locally, and this binding can be locally renamed. External
|
|
names, in contrast, have global scope by default, and a member
|
|
definition does not bind an external name. Instead, a member
|
|
definition refers to an existing binding for an external name, where
|
|
the member name is bound to a <span style="font-style: italic">member key</span>; a class ultimately
|
|
maps member keys to methods, fields, and initialization arguments.</p><p>Recall the <span class="RktSym">hungry-fish%</span> <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span> expression:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">hungry-fish%</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span><span class="hspace"> </span><span class="RktSym">fish%</span><span class="hspace"> </span><span class="RktSym">....</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._inherit%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">inherit</a></span><span class="hspace"> </span><span class="RktSym">eat</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Fpublic%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/public</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">eat-more</span><span class="hspace"> </span><span class="RktSym">fish1</span><span class="hspace"> </span><span class="RktSym">fish2</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">eat</span><span class="hspace"> </span><span class="RktSym">fish1</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">eat</span><span class="hspace"> </span><span class="RktSym">fish2</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p>During its evaluation, the <span class="RktSym">hungry-fish%</span> and <span class="RktSym">fish%</span>
|
|
classes refer to the same global binding of <span class="RktSym">eat</span>. At run
|
|
time, calls to <span class="RktSym">eat</span> in <span class="RktSym">hungry-fish%</span> are matched with
|
|
the <span class="RktSym">eat</span> method in <span class="RktSym">fish%</span> through the shared method
|
|
key that is bound to <span class="RktSym">eat</span>.</p><p>The default binding for an external name is global, but a
|
|
programmer can introduce an external-name binding with the
|
|
<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define-member-name%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define-member-name</a></span> form.</p><blockquote class="leftindent"><blockquote class="SVInsetFlow"><table cellspacing="0" cellpadding="0" class="boxed RBoxed"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define-member-name%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define-member-name</a></span><span class="hspace"> </span><span class="RktVar">id</span><span class="hspace"> </span><span class="RktVar">member-key-expr</span><span class="RktPn">)</span></td></tr></table></blockquote></blockquote><p>In particular, by using <span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528def._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._generate-member-key%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">generate-member-key</a></span><span class="RktPn">)</span> as the
|
|
<span class="RktSym">member-key-expr</span>, an external name can be localized for a
|
|
particular scope, because the generated member key is inaccessible
|
|
outside the scope. In other words, <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define-member-name%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define-member-name</a></span> gives
|
|
an external name a kind of package-private scope, but generalized from
|
|
packages to arbitrary binding scopes in Racket.</p><p>For example, the following <span class="RktSym">fish%</span> and <span class="RktSym">pond%</span> classes cooperate
|
|
via a <span class="RktSym">get-depth</span> method that is only accessible to the
|
|
cooperating classes:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._define-values%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define-values</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">fish%</span><span class="hspace"> </span><span class="RktSym">pond%</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">two mutually recursive classes</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=let.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fletstx-scheme..rkt%2529._let%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">let</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define-member-name%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define-member-name</a></span><span class="hspace"> </span><span class="RktSym">get-depth</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528def._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._generate-member-key%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">generate-member-key</a></span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">fish%</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span><span class="hspace"> </span><span class="RktSym">....</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">my-depth</span><span class="hspace"> </span><span class="RktSym">....</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">my-pond</span><span class="hspace"> </span><span class="RktSym">....</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Fpublic%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/public</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">dive</span><span class="hspace"> </span><span class="RktSym">amt</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=set_.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._set%2521%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">set!</a></span><span class="hspace"> </span><span class="RktSym">my-depth</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=generic-numbers.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._min%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">min</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=generic-numbers.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._%252B%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktSym">my-depth</span><span class="hspace"> </span><span class="RktSym">amt</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._send%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">send</a></span><span class="hspace"> </span><span class="RktSym">my-pond</span><span class="hspace"> </span><span class="RktSym">get-depth</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">pond%</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span><span class="hspace"> </span><span class="RktSym">....</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">current-depth</span><span class="hspace"> </span><span class="RktSym">....</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Fpublic%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/public</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">get-depth</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">current-depth</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=values.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._values%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">values</a></span><span class="hspace"> </span><span class="RktSym">fish%</span><span class="hspace"> </span><span class="RktSym">pond%</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p>External names are in a namespace that separates them from other Racket
|
|
names. This separate namespace is implicitly used for the method name in
|
|
<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._send%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">send</a></span>, for initialization-argument names in <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">new</a></span>, or for
|
|
the external name in a member definition. The special form
|
|
<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._member-name-key%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">member-name-key</a></span> provides access to the binding of an external name
|
|
in an arbitrary expression position: <span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._member-name-key%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">member-name-key</a></span><span class="stt"> </span><span class="RktSym">id</span><span class="RktPn">)</span>
|
|
produces the member-key binding of <span class="RktSym">id</span> in the current scope.</p><p>A member-key value is primarily used with a
|
|
<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define-member-name%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define-member-name</a></span> form. Normally, then,
|
|
<span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._member-name-key%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">member-name-key</a></span><span class="stt"> </span><span class="RktSym">id</span><span class="RktPn">)</span> captures the method key of <span class="RktSym">id</span>
|
|
so that it can be communicated to a use of <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define-member-name%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define-member-name</a></span>
|
|
in a different scope. This capability turns out to be useful for
|
|
generalizing mixins, as discussed next.</p><h4 x-source-module="(lib "scribblings/guide/guide.scrbl")" x-source-pkg="racket-doc" x-part-tag=""Mixins"">13.7<tt> </tt><a name="(part._.Mixins)"></a>Mixins</h4><p>Since <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span> is an expression form instead of a top-level
|
|
declaration as in Smalltalk and Java, a <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span> form can be
|
|
nested inside any lexical scope, including <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=lambda.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._lambda%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">lambda</a></span>. The result
|
|
is a <a name="(tech._mixin)"></a><span style="font-style: italic">mixin</span>, i.e., a class extension that is parameterized
|
|
with respect to its superclass.</p><p>For example, we can parameterize the <span class="RktSym">picky-fish%</span> class over
|
|
its superclass to define <span class="RktSym">picky-mixin</span>:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">picky-mixin</span><span class="hspace"> </span><span class="RktSym">%</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span><span class="hspace"> </span><span class="RktSym">%</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._super-new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">super-new</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Foverride%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/override</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">grow</span><span class="hspace"> </span><span class="RktSym">amt</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._super%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">super</a></span><span class="hspace"> </span><span class="RktSym">grow</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=generic-numbers.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._%252A%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">*</a></span><span class="hspace"> </span><span class="RktVal">3/4</span><span class="hspace"> </span><span class="RktSym">amt</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">picky-fish%</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">picky-mixin</span><span class="hspace"> </span><span class="RktSym">fish%</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p>Many small differences between Smalltalk-style classes and Racket
|
|
classes contribute to the effective use of mixins. In particular, the
|
|
use of <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Foverride%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/override</a></span> makes explicit that
|
|
<span class="RktSym">picky-mixin</span> expects a class with a <span class="RktSym">grow</span> method. If
|
|
<span class="RktSym">picky-mixin</span> is applied to a class without a <span class="RktSym">grow</span>
|
|
method, an error is signaled as soon as <span class="RktSym">picky-mixin</span> is
|
|
applied.</p><p>Similarly, a use of <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._inherit%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">inherit</a></span> enforces a “method existence”
|
|
requirement when the mixin is applied:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">hungry-mixin</span><span class="hspace"> </span><span class="RktSym">%</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span><span class="hspace"> </span><span class="RktSym">%</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._super-new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">super-new</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._inherit%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">inherit</a></span><span class="hspace"> </span><span class="RktSym">eat</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Fpublic%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/public</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">eat-more</span><span class="hspace"> </span><span class="RktSym">fish1</span><span class="hspace"> </span><span class="RktSym">fish2</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">eat</span><span class="hspace"> </span><span class="RktSym">fish1</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">eat</span><span class="hspace"> </span><span class="RktSym">fish2</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p>The advantage of mixins is that we can easily combine them to create
|
|
new classes whose implementation sharing does not fit into a
|
|
single-inheritance hierarchy—<wbr></wbr>without the ambiguities associated with
|
|
multiple inheritance. Equipped with <span class="RktSym">picky-mixin</span> and
|
|
<span class="RktSym">hungry-mixin</span>, creating a class for a hungry, yet picky fish
|
|
is straightforward:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">picky-hungry-fish%</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">hungry-mixin</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">picky-mixin</span><span class="hspace"> </span><span class="RktSym">fish%</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p>The use of keyword initialization arguments is critical for the easy
|
|
use of mixins. For example, <span class="RktSym">picky-mixin</span> and
|
|
<span class="RktSym">hungry-mixin</span> can augment any class with suitable <span class="RktSym">eat</span>
|
|
and <span class="RktSym">grow</span> methods, because they do not specify initialization
|
|
arguments and add none in their <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._super-new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">super-new</a></span> expressions:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">person%</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528def._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._object%7E25%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">object%</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._init%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">init</a></span><span class="hspace"> </span><span class="RktSym">name</span><span class="hspace"> </span><span class="RktSym">age</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">....</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Fpublic%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/public</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">eat</span><span class="hspace"> </span><span class="RktSym">food</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">....</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Fpublic%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/public</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">grow</span><span class="hspace"> </span><span class="RktSym">amt</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">....</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">child%</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">hungry-mixin</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">picky-mixin</span><span class="hspace"> </span><span class="RktSym">person%</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">oliver</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">new</a></span><span class="hspace"> </span><span class="RktSym">child%</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">name</span><span class="hspace"> </span><span class="RktVal">"Oliver"</span><span class="RktPn">]</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">age</span><span class="hspace"> </span><span class="RktVal">6</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p>Finally, the use of external names for class members (instead of
|
|
lexically scoped identifiers) makes mixin use convenient. Applying
|
|
<span class="RktSym">picky-mixin</span> to <span class="RktSym">person%</span> works because the names
|
|
<span class="RktSym">eat</span> and <span class="RktSym">grow</span> match, without any a priori declaration
|
|
that <span class="RktSym">eat</span> and <span class="RktSym">grow</span> should be the same method in
|
|
<span class="RktSym">fish%</span> and <span class="RktSym">person%</span>. This feature is a potential
|
|
drawback when member names collide accidentally; some accidental
|
|
collisions can be corrected by limiting the scope external names, as
|
|
discussed in <a href="classes.html#%28part._extnames%29" data-pltdoc="x">Controlling the Scope of External Names</a>.</p><h5 x-source-module="(lib "scribblings/guide/guide.scrbl")" x-source-pkg="racket-doc" x-part-tag=""Mixins_and_Interfaces"">13.7.1<tt> </tt><a name="(part._.Mixins_and_.Interfaces)"></a>Mixins and Interfaces</h5><p>Using <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objectutils.html%23%2528def._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._implementation%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">implementation?</a></span>, <span class="RktSym">picky-mixin</span> could require
|
|
that its base class implements <span class="RktSym">grower-interface</span>, which could
|
|
be implemented by both <span class="RktSym">fish%</span> and <span class="RktSym">person%</span>:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">grower-interface</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createinterface.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._interface%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">interface</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">grow</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">picky-mixin</span><span class="hspace"> </span><span class="RktSym">%</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=when_unless.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fletstx-scheme..rkt%2529._unless%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">unless</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objectutils.html%23%2528def._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._implementation%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">implementation?</a></span><span class="hspace"> </span><span class="RktSym">%</span><span class="hspace"> </span><span class="RktSym">grower-interface</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=exns.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._error%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">error</a></span><span class="hspace"> </span><span class="RktVal">"picky-mixin: not a grower-interface class"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span><span class="hspace"> </span><span class="RktSym">%</span><span class="hspace"> </span><span class="RktSym">....</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p>Another use of interfaces with a mixin is to tag classes generated by
|
|
the mixin, so that instances of the mixin can be recognized. In other
|
|
words, <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objectutils.html%23%2528def._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._is-a%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">is-a?</a></span> cannot work on a mixin represented as a
|
|
function, but it can recognize an interface (somewhat like a
|
|
<span style="font-style: italic">specialization interface</span>) that is consistently implemented
|
|
by the mixin. For example, classes generated by <span class="RktSym">picky-mixin</span>
|
|
could be tagged with <span class="RktSym">picky-interface</span>, enabling the
|
|
<span class="RktSym">is-picky?</span> predicate:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">picky-interface</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createinterface.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._interface%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">interface</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">picky-mixin</span><span class="hspace"> </span><span class="RktSym">%</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=when_unless.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fletstx-scheme..rkt%2529._unless%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">unless</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objectutils.html%23%2528def._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._implementation%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">implementation?</a></span><span class="hspace"> </span><span class="RktSym">%</span><span class="hspace"> </span><span class="RktSym">grower-interface</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=exns.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._error%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">error</a></span><span class="hspace"> </span><span class="RktVal">"picky-mixin: not a grower-interface class"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%252A%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class*</a></span><span class="hspace"> </span><span class="RktSym">%</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">picky-interface</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">....</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">is-picky?</span><span class="hspace"> </span><span class="RktSym">o</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objectutils.html%23%2528def._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._is-a%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">is-a?</a></span><span class="hspace"> </span><span class="RktSym">o</span><span class="hspace"> </span><span class="RktSym">picky-interface</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><h5 x-source-module="(lib "scribblings/guide/guide.scrbl")" x-source-pkg="racket-doc" x-part-tag=""The_mixin_Form"">13.7.2<tt> </tt><a name="(part._.The_mixin_.Form)"></a>The <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=mixins.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._mixin%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">mixin</a></span> Form</h5><p>To codify the <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=lambda.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._lambda%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">lambda</a></span>-plus-<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span> pattern for
|
|
implementing mixins, including the use of interfaces for the domain
|
|
and range of the mixin, the class system provides a <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=mixins.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._mixin%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">mixin</a></span>
|
|
macro:</p><blockquote class="leftindent"><blockquote class="SVInsetFlow"><table cellspacing="0" cellpadding="0" class="boxed RBoxed"><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=mixins.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._mixin%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">mixin</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktVar">interface-expr</span><span class="hspace"> </span><span class="RktMeta">...</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktVar">interface-expr</span><span class="hspace"> </span><span class="RktMeta">...</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVar">decl-or-expr</span><span class="hspace"> </span><span class="RktMeta">...</span><span class="RktPn">)</span></td></tr></table></td></tr></table></blockquote></blockquote><p>The first set of <span class="RktSym">interface-expr</span>s determines the domain of the
|
|
mixin, and the second set determines the range. That is, the expansion
|
|
is a function that tests whether a given base class implements the
|
|
first sequence of <span class="RktSym">interface-expr</span>s and produces a class that
|
|
implements the second sequence of <span class="RktSym">interface-expr</span>s. Other
|
|
requirements, such as the presence of <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._inherit%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">inherit</a></span>ed methods in
|
|
the superclass, are then checked for the <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span> expansion of
|
|
the <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=mixins.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._mixin%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">mixin</a></span> form. For example:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">choosy-interface</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createinterface.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._interface%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">interface</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">choose?</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">hungry-interface</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createinterface.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._interface%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">interface</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">eat</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">choosy-eater-mixin</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=mixins.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._mixin%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">mixin</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">choosy-interface</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">hungry-interface</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._inherit%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">inherit</a></span><span class="hspace"> </span><span class="RktSym">choose?</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._super-new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">super-new</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Fpublic%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/public</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">eat</span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=if.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fletstx-scheme..rkt%2529._cond%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym">choose?</span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=Writing.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._printf%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">printf</a></span><span class="hspace"> </span><span class="RktVal">"chomp chomp chomp on ~a.\n"</span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=if.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fletstx-scheme..rkt%2529._else%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=Writing.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._printf%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">printf</a></span><span class="hspace"> </span><span class="RktVal">"I'm not crazy about ~a.\n"</span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">herring-lover%</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%252A%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class*</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528def._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._object%7E25%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">object%</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">choosy-interface</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._super-new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">super-new</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Fpublic%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/public</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">choose?</span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=regexp.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._regexp-match%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">regexp-match</a></span><span class="hspace"> </span><span class="RktVal">#px"^herring"</span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">herring-eater%</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">choosy-eater-mixin</span><span class="hspace"> </span><span class="RktSym">herring-lover%</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">eater</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">new</a></span><span class="hspace"> </span><span class="RktSym">herring-eater%</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._send%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">send</a></span><span class="hspace"> </span><span class="RktSym">eater</span><span class="hspace"> </span><span class="RktSym">eat</span><span class="hspace"> </span><span class="RktVal">"elderberry"</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktOut">I'm not crazy about elderberry.</span></p></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._send%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">send</a></span><span class="hspace"> </span><span class="RktSym">eater</span><span class="hspace"> </span><span class="RktSym">eat</span><span class="hspace"> </span><span class="RktVal">"herring"</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktOut">chomp chomp chomp on herring.</span></p></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._send%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">send</a></span><span class="hspace"> </span><span class="RktSym">eater</span><span class="hspace"> </span><span class="RktSym">eat</span><span class="hspace"> </span><span class="RktVal">"herring ice cream"</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktOut">chomp chomp chomp on herring ice cream.</span></p></td></tr></table></blockquote><p>Mixins not only override methods and introduce public methods, they
|
|
can also augment methods, introduce augment-only methods, add an
|
|
overrideable augmentation, and add an augmentable override —<wbr></wbr> all of
|
|
the things that a class can do (see <a href="classes.html#%28part._inner%29" data-pltdoc="x">Final, Augment, and Inner</a>).</p><h5 x-source-module="(lib "scribblings/guide/guide.scrbl")" x-source-pkg="racket-doc" x-part-tag=""parammixins"">13.7.3<tt> </tt><a name="(part._parammixins)"></a>Parameterized Mixins</h5><p>As noted in <a href="classes.html#%28part._extnames%29" data-pltdoc="x">Controlling the Scope of External Names</a>, external names can be bound with
|
|
<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define-member-name%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define-member-name</a></span>. This facility allows a mixin to be
|
|
generalized with respect to the methods that it defines and uses. For
|
|
example, we can parameterize <span class="RktSym">hungry-mixin</span> with respect to the
|
|
external member key for <span class="RktSym">eat</span>:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-hungry-mixin</span><span class="hspace"> </span><span class="RktSym">eat-method-key</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define-member-name%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define-member-name</a></span><span class="hspace"> </span><span class="RktSym">eat</span><span class="hspace"> </span><span class="RktSym">eat-method-key</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=mixins.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._mixin%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">mixin</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._super-new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">super-new</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._inherit%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">inherit</a></span><span class="hspace"> </span><span class="RktSym">eat</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Fpublic%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/public</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">eat-more</span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktSym">y</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">eat</span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">eat</span><span class="hspace"> </span><span class="RktSym">y</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p>To obtain a particular hungry-mixin, we must apply this function to a
|
|
member key that refers to a suitable
|
|
<span class="RktSym">eat</span> method, which we can obtain using <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._member-name-key%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">member-name-key</a></span>:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym">make-hungry-mixin</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._member-name-key%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">member-name-key</a></span><span class="hspace"> </span><span class="RktSym">eat</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528def._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._object%7E25%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">object%</a></span><span class="hspace"> </span><span class="RktSym">....</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Fpublic%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/public</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">eat</span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">yum</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p>Above, we apply <span class="RktSym">hungry-mixin</span> to an anonymous class that provides
|
|
<span class="RktSym">eat</span>, but we can also combine it with a class that provides
|
|
<span class="RktSym">chomp</span>, instead:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym">make-hungry-mixin</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._member-name-key%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">member-name-key</a></span><span class="hspace"> </span><span class="RktSym">chomp</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528def._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._object%7E25%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">object%</a></span><span class="hspace"> </span><span class="RktSym">....</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Fpublic%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/public</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">chomp</span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">yum</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><h4 x-source-module="(lib "scribblings/guide/guide.scrbl")" x-source-pkg="racket-doc" x-part-tag=""Traits"">13.8<tt> </tt><a name="(part._.Traits)"></a>Traits</h4><p>A <span style="font-style: italic">trait</span> is similar to a mixin, in that it encapsulates a set
|
|
of methods to be added to a class. A trait is different from a mixin
|
|
in that its individual methods can be manipulated with trait operators
|
|
such as <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=trait.html%23%2528def._%2528%2528lib._racket%252Ftrait..rkt%2529._trait-sum%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">trait-sum</a></span> (merge the methods of two traits), <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=trait.html%23%2528form._%2528%2528lib._racket%252Ftrait..rkt%2529._trait-exclude%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">trait-exclude</a></span>
|
|
(remove a method from a trait), and <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=trait.html%23%2528form._%2528%2528lib._racket%252Ftrait..rkt%2529._trait-alias%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">trait-alias</a></span> (add a copy of a
|
|
method with a new name; do not redirect any calls to the old name).</p><p>The practical difference between mixins and traits is that two traits
|
|
can be combined, even if they include a common method and even if
|
|
neither method can sensibly override the other. In that case, the
|
|
programmer must explicitly resolve the collision, usually by aliasing
|
|
methods, excluding methods, and merging a new trait that uses the
|
|
aliases.</p><p>Suppose our <span class="RktSym">fish%</span> programmer wants to define two class
|
|
extensions, <span class="RktSym">spots</span> and <span class="RktSym">stripes</span>, each of which
|
|
includes a <span class="RktSym">get-color</span> method. The fish’s spot color should not
|
|
override the stripe color nor vice versa; instead, a
|
|
<span class="RktSym">spots+stripes-fish%</span> should combine the two colors, which is
|
|
not possible if <span class="RktSym">spots</span> and <span class="RktSym">stripes</span> are implemented as
|
|
plain mixins. If, however, <span class="RktSym">spots</span> and <span class="RktSym">stripes</span> are
|
|
implemented as traits, they can be combined. First, we alias
|
|
<span class="RktSym">get-color</span> in each trait to a non-conflicting name. Second,
|
|
the <span class="RktSym">get-color</span> methods are removed from both and the traits
|
|
with only aliases are merged. Finally, the new trait is used to create
|
|
a class that introduces its own <span class="RktSym">get-color</span> method based on the
|
|
two aliases, producing the desired <span class="RktSym">spots+stripes</span> extension.</p><h5 x-source-module="(lib "scribblings/guide/guide.scrbl")" x-source-pkg="racket-doc" x-part-tag=""Traits_as_Sets_of_Mixins"">13.8.1<tt> </tt><a name="(part._.Traits_as_.Sets_of_.Mixins)"></a>Traits as Sets of Mixins</h5><p>One natural approach to implementing traits in Racket is as a set
|
|
of mixins, with one mixin per trait method. For example, we might
|
|
attempt to define the spots and stripes traits as follows, using
|
|
association lists to represent sets:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">spots-trait</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._list%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._cons%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">get-color</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=lambda.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._lambda%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">%</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span><span class="hspace"> </span><span class="RktSym">%</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._super-new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">super-new</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Fpublic%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/public</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">get-color</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">black</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">stripes-trait</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._list%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._cons%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">get-color</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=lambda.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._lambda%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">%</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span><span class="hspace"> </span><span class="RktSym">%</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._super-new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">super-new</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Fpublic%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/public</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">get-color</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">red</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p>A set representation, such as the above, allows <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=trait.html%23%2528def._%2528%2528lib._racket%252Ftrait..rkt%2529._trait-sum%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">trait-sum</a></span> and
|
|
<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=trait.html%23%2528form._%2528%2528lib._racket%252Ftrait..rkt%2529._trait-exclude%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">trait-exclude</a></span> as simple manipulations; unfortunately, it does
|
|
not support the <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=trait.html%23%2528form._%2528%2528lib._racket%252Ftrait..rkt%2529._trait-alias%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">trait-alias</a></span> operator. Although a mixin can be
|
|
duplicated in the association list, the mixin has a fixed method name,
|
|
e.g., <span class="RktSym">get-color</span>, and mixins do not support a method-rename
|
|
operation. To support <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=trait.html%23%2528form._%2528%2528lib._racket%252Ftrait..rkt%2529._trait-alias%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">trait-alias</a></span>, we must parameterize the
|
|
mixins over the external method name in the same way that <span class="RktSym">eat</span>
|
|
was parameterized in <a href="classes.html#%28part._parammixins%29" data-pltdoc="x">Parameterized Mixins</a>.</p><p>To support the <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=trait.html%23%2528form._%2528%2528lib._racket%252Ftrait..rkt%2529._trait-alias%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">trait-alias</a></span> operation, <span class="RktSym">spots-trait</span>
|
|
should be represented as:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">spots-trait</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._list%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._cons%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._member-name-key%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">member-name-key</a></span><span class="hspace"> </span><span class="RktSym">get-color</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=lambda.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._lambda%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">get-color-key</span><span class="hspace"> </span><span class="RktSym">%</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define-member-name%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define-member-name</a></span><span class="hspace"> </span><span class="RktSym">get-color</span><span class="hspace"> </span><span class="RktSym">get-color-key</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span><span class="hspace"> </span><span class="RktSym">%</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._super-new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">super-new</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Fpublic%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/public</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">get-color</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">black</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p>When the <span class="RktSym">get-color</span> method in <span class="RktSym">spots-trait</span> is aliased
|
|
to <span class="RktSym">get-trait-color</span> and the <span class="RktSym">get-color</span> method is
|
|
removed, the resulting trait is the same as</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._list%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._cons%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._member-name-key%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">member-name-key</a></span><span class="hspace"> </span><span class="RktSym">get-trait-color</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=lambda.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._lambda%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">get-color-key</span><span class="hspace"> </span><span class="RktSym">%</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define-member-name%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define-member-name</a></span><span class="hspace"> </span><span class="RktSym">get-color</span><span class="hspace"> </span><span class="RktSym">get-color-key</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span><span class="hspace"> </span><span class="RktSym">%</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._super-new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">super-new</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Fpublic%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/public</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">get-color</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">black</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p>To apply a trait <span class="RktVar">T</span> to a class <span class="RktVar">C</span> and obtain a derived
|
|
class, we use <span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=trait.html%23%2528def._%2528%2528lib._racket%252Ftrait..rkt%2529._trait-%7E3emixin%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">trait->mixin</a></span><span class="stt"> </span><span class="RktVar">T</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktVar">C</span><span class="RktPn">)</span>. The <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=trait.html%23%2528def._%2528%2528lib._racket%252Ftrait..rkt%2529._trait-%7E3emixin%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">trait->mixin</a></span>
|
|
function supplies each mixin of <span class="RktVar">T</span> with the key for the mixin’s
|
|
method and a partial extension of <span class="RktVar">C</span>:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=trait.html%23%2528def._%2528%2528lib._racket%252Ftrait..rkt%2529._trait-%7E3emixin%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">trait->mixin</a></span><span class="hspace"> </span><span class="RktSym">T</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">C</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528lib._racket%252Fprivate%252Flist..rkt%2529._foldr%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">foldr</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=lambda.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._lambda%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">m</span><span class="hspace"> </span><span class="RktSym">%</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._cdr%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">cdr</a></span><span class="hspace"> </span><span class="RktSym">m</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._car%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">car</a></span><span class="hspace"> </span><span class="RktSym">m</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">%</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">C</span><span class="hspace"> </span><span class="RktSym">T</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p>Thus, when the trait above is combined with other traits and then
|
|
applied to a class, the use of <span class="RktSym">get-color</span> becomes a reference
|
|
to the external name <span class="RktSym">get-trait-color</span>.</p><h5 x-source-module="(lib "scribblings/guide/guide.scrbl")" x-source-pkg="racket-doc" x-part-tag=""Inherit_and_Super_in_Traits"">13.8.2<tt> </tt><a name="(part._.Inherit_and_.Super_in_.Traits)"></a>Inherit and Super in Traits</h5><p>This first implementation of traits supports <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=trait.html%23%2528form._%2528%2528lib._racket%252Ftrait..rkt%2529._trait-alias%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">trait-alias</a></span>, and it
|
|
supports a trait method that calls itself, but it does not support
|
|
trait methods that call each other. In particular, suppose that a spot-fish’s
|
|
market value depends on the color of its spots:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">spots-trait</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._list%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._cons%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._member-name-key%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">member-name-key</a></span><span class="hspace"> </span><span class="RktSym">get-color</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">....</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._cons%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._member-name-key%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">member-name-key</a></span><span class="hspace"> </span><span class="RktSym">get-price</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=lambda.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._lambda%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">get-price</span><span class="hspace"> </span><span class="RktSym">%</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">....</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span><span class="hspace"> </span><span class="RktSym">%</span><span class="hspace"> </span><span class="RktSym">....</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Fpublic%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/public</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">get-price</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">....</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">get-color</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">....</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p>In this case, the definition of <span class="RktSym">spots-trait</span> fails, because
|
|
<span class="RktSym">get-color</span> is not in scope for the <span class="RktSym">get-price</span>
|
|
mixin. Indeed, depending on the order of mixin application when the
|
|
trait is applied to a class, the <span class="RktSym">get-color</span> method may not be
|
|
available when <span class="RktSym">get-price</span> mixin is applied to the class.
|
|
Therefore adding an <span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._inherit%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">inherit</a></span><span class="stt"> </span><span class="RktSym">get-color</span><span class="RktPn">)</span> declaration to the
|
|
<span class="RktSym">get-price</span> mixin does not solve the problem.</p><p>One solution is to require the use of <span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._send%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">send</a></span><span class="stt"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._this%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">this</a></span><span class="stt"> </span><span class="RktSym">get-color</span><span class="RktPn">)</span> in
|
|
methods such as <span class="RktSym">get-price</span>. This change works because
|
|
<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._send%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">send</a></span> always delays the method lookup until the method call is
|
|
evaluated. The delayed lookup is more expensive than a direct call,
|
|
however. Worse, it also delays checking whether a <span class="RktSym">get-color</span> method
|
|
even exists.</p><p>A second, effective, and efficient solution is to change the encoding
|
|
of traits. Specifically, we represent each method as a pair of mixins:
|
|
one that introduces the method and one that implements it. When a
|
|
trait is applied to a class, all of the method-introducing mixins are
|
|
applied first. Then the method-implementing mixins can use
|
|
<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._inherit%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">inherit</a></span> to directly access any introduced method.</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">spots-trait</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._list%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._list%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">local-member-name-key</span><span class="hspace"> </span><span class="RktSym">get-color</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=lambda.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._lambda%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">get-color</span><span class="hspace"> </span><span class="RktSym">get-price</span><span class="hspace"> </span><span class="RktSym">%</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">....</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span><span class="hspace"> </span><span class="RktSym">%</span><span class="hspace"> </span><span class="RktSym">....</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Fpublic%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/public</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">get-color</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=void.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._void%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">void</a></span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=lambda.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._lambda%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">get-color</span><span class="hspace"> </span><span class="RktSym">get-price</span><span class="hspace"> </span><span class="RktSym">%</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">....</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span><span class="hspace"> </span><span class="RktSym">%</span><span class="hspace"> </span><span class="RktSym">....</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Foverride%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/override</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">get-color</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">black</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._list%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">local-member-name-key</span><span class="hspace"> </span><span class="RktSym">get-price</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=lambda.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._lambda%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">get-price</span><span class="hspace"> </span><span class="RktSym">get-color</span><span class="hspace"> </span><span class="RktSym">%</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">....</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span><span class="hspace"> </span><span class="RktSym">%</span><span class="hspace"> </span><span class="RktSym">....</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Fpublic%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/public</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">get-price</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=void.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._void%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">void</a></span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=lambda.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._lambda%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">get-color</span><span class="hspace"> </span><span class="RktSym">get-price</span><span class="hspace"> </span><span class="RktSym">%</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">....</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span><span class="hspace"> </span><span class="RktSym">%</span><span class="hspace"> </span><span class="RktSym">....</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._inherit%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">inherit</a></span><span class="hspace"> </span><span class="RktSym">get-color</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Foverride%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/override</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">get-price</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">....</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">get-color</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">....</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p>With this trait encoding, <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=trait.html%23%2528form._%2528%2528lib._racket%252Ftrait..rkt%2529._trait-alias%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">trait-alias</a></span> adds a new method with
|
|
a new name, but it does not change any references to the old method.</p><h5 x-source-module="(lib "scribblings/guide/guide.scrbl")" x-source-pkg="racket-doc" x-part-tag=""The_trait_Form"">13.8.3<tt> </tt><a name="(part._.The_trait_.Form)"></a>The <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=trait.html%23%2528form._%2528%2528lib._racket%252Ftrait..rkt%2529._trait%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">trait</a></span> Form</h5><p>The general-purpose trait pattern is clearly too complex for a
|
|
programmer to use directly, but it is easily codified in a
|
|
<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=trait.html%23%2528form._%2528%2528lib._racket%252Ftrait..rkt%2529._trait%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">trait</a></span> macro:</p><blockquote class="leftindent"><blockquote class="SVInsetFlow"><table cellspacing="0" cellpadding="0" class="boxed RBoxed"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=trait.html%23%2528form._%2528%2528lib._racket%252Ftrait..rkt%2529._trait%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">trait</a></span><span class="hspace"> </span><span class="RktVar">trait-clause</span><span class="hspace"> </span><span class="RktMeta">...</span><span class="RktPn">)</span></td></tr></table></blockquote></blockquote><p>The <span class="RktSym">id</span>s in the optional <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._inherit%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">inherit</a></span> clause are available for direct
|
|
reference in the method <span class="RktSym">expr</span>s, and they must be supplied
|
|
either by other traits or the base class to which
|
|
the trait is ultimately applied.</p><p>Using this form in conjunction with trait operators such as
|
|
<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=trait.html%23%2528def._%2528%2528lib._racket%252Ftrait..rkt%2529._trait-sum%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">trait-sum</a></span>, <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=trait.html%23%2528form._%2528%2528lib._racket%252Ftrait..rkt%2529._trait-exclude%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">trait-exclude</a></span>, <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=trait.html%23%2528form._%2528%2528lib._racket%252Ftrait..rkt%2529._trait-alias%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">trait-alias</a></span>, and
|
|
<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=trait.html%23%2528def._%2528%2528lib._racket%252Ftrait..rkt%2529._trait-%7E3emixin%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">trait->mixin</a></span>, we can implement <span class="RktSym">spots-trait</span> and
|
|
<span class="RktSym">stripes-trait</span> as desired.</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">spots-trait</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=trait.html%23%2528form._%2528%2528lib._racket%252Ftrait..rkt%2529._trait%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">trait</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Fpublic%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/public</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">get-color</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">black</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Fpublic%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/public</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">get-price</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=stx-patterns.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fstxcase-scheme..rkt%2529._......%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">...</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">get-color</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=stx-patterns.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fstxcase-scheme..rkt%2529._......%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">stripes-trait</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=trait.html%23%2528form._%2528%2528lib._racket%252Ftrait..rkt%2529._trait%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">trait</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Fpublic%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/public</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">get-color</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">red</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">spots+stripes-trait</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=trait.html%23%2528def._%2528%2528lib._racket%252Ftrait..rkt%2529._trait-sum%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">trait-sum</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=trait.html%23%2528form._%2528%2528lib._racket%252Ftrait..rkt%2529._trait-exclude%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">trait-exclude</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=trait.html%23%2528form._%2528%2528lib._racket%252Ftrait..rkt%2529._trait-alias%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">trait-alias</a></span><span class="hspace"> </span><span class="RktSym">spots-trait</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">get-color</span><span class="hspace"> </span><span class="RktSym">get-spots-color</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">get-color</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=trait.html%23%2528form._%2528%2528lib._racket%252Ftrait..rkt%2529._trait-exclude%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">trait-exclude</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=trait.html%23%2528form._%2528%2528lib._racket%252Ftrait..rkt%2529._trait-alias%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">trait-alias</a></span><span class="hspace"> </span><span class="RktSym">stripes-trait</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">get-color</span><span class="hspace"> </span><span class="RktSym">get-stripes-color</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">get-color</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=trait.html%23%2528form._%2528%2528lib._racket%252Ftrait..rkt%2529._trait%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">trait</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._inherit%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">inherit</a></span><span class="hspace"> </span><span class="RktSym">get-spots-color</span><span class="hspace"> </span><span class="RktSym">get-stripes-color</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Fpublic%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/public</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">get-color</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">....</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">get-spots-color</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">....</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">get-stripes-color</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">....</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><h4 x-source-module="(lib "scribblings/guide/guide.scrbl")" x-source-pkg="racket-doc" x-part-tag=""Class_Contracts"">13.9<tt> </tt><a name="(part._.Class_.Contracts)"></a>Class Contracts</h4><p>As classes are values, they can flow across contract boundaries, and we
|
|
may wish to protect parts of a given class with contracts. For this,
|
|
the <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=Object_and_Class_Contracts.html%23%2528form._%2528%2528lib._racket%252Fclass..rkt%2529._class%252Fc%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class/c</a></span> form is used. The <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=Object_and_Class_Contracts.html%23%2528form._%2528%2528lib._racket%252Fclass..rkt%2529._class%252Fc%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class/c</a></span> form has many
|
|
subforms, which describe two types of contracts on fields and methods:
|
|
those that affect uses via instantiated objects and those that affect
|
|
subclasses.</p><h5 x-source-module="(lib "scribblings/guide/guide.scrbl")" x-source-pkg="racket-doc" x-part-tag=""External_Class_Contracts"">13.9.1<tt> </tt><a name="(part._.External_.Class_.Contracts)"></a>External Class Contracts</h5><p>In its simplest form, <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=Object_and_Class_Contracts.html%23%2528form._%2528%2528lib._racket%252Fclass..rkt%2529._class%252Fc%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class/c</a></span> protects the public fields and methods
|
|
of objects instantiated from the contracted class. There is also an
|
|
<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=Object_and_Class_Contracts.html%23%2528form._%2528%2528lib._racket%252Fclass..rkt%2529._object%252Fc%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">object/c</a></span> form that can be used to similarly protect the public fields
|
|
and methods of a particular object. Take the following definition of
|
|
<span class="RktSym">animal%</span>, which uses a public field for its <span class="RktSym">size</span> attribute:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">animal%</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528def._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._object%7E25%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">object%</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._super-new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">super-new</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._field%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">field</a></span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">size</span><span class="hspace"> </span><span class="RktVal">10</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Fpublic%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/public</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">eat</span><span class="hspace"> </span><span class="RktSym">food</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=set_.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._set%2521%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">set!</a></span><span class="hspace"> </span><span class="RktSym">size</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=generic-numbers.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._%252B%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktSym">size</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._get-field%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">get-field</a></span><span class="hspace"> </span><span class="RktSym">size</span><span class="hspace"> </span><span class="RktSym">food</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p>For any instantiated <span class="RktSym">animal%</span>, accessing the <span class="RktSym">size</span> field
|
|
should return a positive number. Also, if the <span class="RktSym">size</span> field is set,
|
|
it should be assigned a positive number. Finally, the <span class="RktSym">eat</span> method
|
|
should receive an argument which is an object with a <span class="RktSym">size</span> field
|
|
that contains a positive number. To ensure these conditions, we will define
|
|
the <span class="RktSym">animal%</span> class with an appropriate contract:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">positive/c</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=data-structure-contracts.html%23%2528def._%2528%2528lib._racket%252Fcontract%252Fbase..rkt%2529._and%252Fc%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">and/c</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=number-types.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._number%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">number?</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=number-types.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._positive%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">positive?</a></span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">edible/c</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=Object_and_Class_Contracts.html%23%2528form._%2528%2528lib._racket%252Fclass..rkt%2529._object%252Fc%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">object/c</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._field%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">field</a></span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">size</span><span class="hspace"> </span><span class="RktSym">positive/c</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=attaching-contracts-to-values.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fregion..rkt%2529._define%252Fcontract%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/contract</a></span><span class="hspace"> </span><span class="RktSym">animal%</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=Object_and_Class_Contracts.html%23%2528form._%2528%2528lib._racket%252Fclass..rkt%2529._class%252Fc%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class/c</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._field%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">field</a></span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">size</span><span class="hspace"> </span><span class="RktSym">positive/c</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">eat</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=Object_and_Class_Contracts.html%23%2528form._%2528%2528lib._racket%252Fclass..rkt%2529._-%7E3em%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span>m</a></span><span class="hspace"> </span><span class="RktSym">edible/c</span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=void.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._void%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">void?</a></span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528def._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._object%7E25%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">object%</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._super-new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">super-new</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._field%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">field</a></span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">size</span><span class="hspace"> </span><span class="RktVal">10</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Fpublic%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/public</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">eat</span><span class="hspace"> </span><span class="RktSym">food</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=set_.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._set%2521%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">set!</a></span><span class="hspace"> </span><span class="RktSym">size</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=generic-numbers.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._%252B%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktSym">size</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._get-field%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">get-field</a></span><span class="hspace"> </span><span class="RktSym">size</span><span class="hspace"> </span><span class="RktSym">food</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p>Here we use <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=Object_and_Class_Contracts.html%23%2528form._%2528%2528lib._racket%252Fclass..rkt%2529._-%7E3em%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span>m</a></span> to describe the behavior of <span class="RktSym">eat</span> since we
|
|
do not need to describe any requirements for the <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._this%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">this</a></span> parameter.
|
|
Now that we have our contracted class, we can see that the contracts
|
|
on both <span class="RktSym">size</span> and <span class="RktSym">eat</span> are enforced:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">bob</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">new</a></span><span class="hspace"> </span><span class="RktSym">animal%</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._set-field%2521%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">set-field!</a></span><span class="hspace"> </span><span class="RktSym">size</span><span class="hspace"> </span><span class="RktSym">bob</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">)</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._get-field%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">get-field</a></span><span class="hspace"> </span><span class="RktSym">size</span><span class="hspace"> </span><span class="RktSym">bob</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">3</span></p></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._set-field%2521%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">set-field!</a></span><span class="hspace"> </span><span class="RktSym">size</span><span class="hspace"> </span><span class="RktSym">bob</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">large</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktErr">animal%: contract violation</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">expected: positive/c</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">given: 'large</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">in: the size field in</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">(class/c</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">(eat</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">(->m</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">(object/c (field (size positive/c)))</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">void?))</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">(field (size positive/c)))</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">contract from: (definition animal%)</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">blaming: top-level</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">(assuming the contract is correct)</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">at: eval:31:0</span></p></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">richie</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">new</a></span><span class="hspace"> </span><span class="RktSym">animal%</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._send%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">send</a></span><span class="hspace"> </span><span class="RktSym">bob</span><span class="hspace"> </span><span class="RktSym">eat</span><span class="hspace"> </span><span class="RktSym">richie</span><span class="RktPn">)</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._get-field%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">get-field</a></span><span class="hspace"> </span><span class="RktSym">size</span><span class="hspace"> </span><span class="RktSym">bob</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">13</span></p></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">rock</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">new</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528def._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._object%7E25%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">object%</a></span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._send%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">send</a></span><span class="hspace"> </span><span class="RktSym">bob</span><span class="hspace"> </span><span class="RktSym">eat</span><span class="hspace"> </span><span class="RktSym">rock</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktErr">eat: contract violation;</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">no public field size</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">in: the 1st argument of</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">the eat method in</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">(class/c</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">(eat</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">(->m</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">(object/c (field (size positive/c)))</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">void?))</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">(field (size positive/c)))</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">contract from: (definition animal%)</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">contract on: animal%</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">blaming: top-level</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">(assuming the contract is correct)</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">at: eval:31:0</span></p></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">giant</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">new</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528def._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._object%7E25%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">object%</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._super-new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">super-new</a></span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._field%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">field</a></span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">size</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">large</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._send%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">send</a></span><span class="hspace"> </span><span class="RktSym">bob</span><span class="hspace"> </span><span class="RktSym">eat</span><span class="hspace"> </span><span class="RktSym">giant</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktErr">eat: contract violation</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">expected: positive/c</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">given: 'large</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">in: the size field in</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">the 1st argument of</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">the eat method in</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">(class/c</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">(eat</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">(->m</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">(object/c (field (size positive/c)))</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">void?))</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">(field (size positive/c)))</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">contract from: (definition animal%)</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">contract on: animal%</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">blaming: top-level</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">(assuming the contract is correct)</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">at: eval:31:0</span></p></td></tr></table></blockquote><p>There are two important caveats for external class contracts. First,
|
|
external method contracts are only enforced when the target of dynamic
|
|
dispatch is the method implementation of the contracted class, which
|
|
lies within the contract boundary. Overriding that implementation, and
|
|
thus changing the target of dynamic dispatch, will mean that the contract
|
|
is no longer enforced for clients, since accessing the method no longer
|
|
crosses the contract boundary. Unlike external method contracts, external
|
|
field contracts are always enforced for clients of subclasses, since fields
|
|
cannot be overridden or shadowed.</p><p>Second, these contracts do not restrict subclasses of <span class="RktSym">animal%</span>
|
|
in any way. Fields and methods that are inherited and used by subclasses
|
|
are not checked by these contracts, and uses of the superclass’s methods
|
|
via <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._super%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">super</a></span> are also unchecked. The following example illustrates
|
|
both caveats:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0"><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">large-animal%</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span><span class="hspace"> </span><span class="RktSym">animal%</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._super-new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">super-new</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._inherit-field%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">inherit-field</a></span><span class="hspace"> </span><span class="RktSym">size</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=set_.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._set%2521%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">set!</a></span><span class="hspace"> </span><span class="RktSym">size</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">large</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Foverride%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/override</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">eat</span><span class="hspace"> </span><span class="RktSym">food</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=Writing.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._display%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">display</a></span><span class="hspace"> </span><span class="RktVal">"Nom nom nom"</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=Byte_and_String_Output.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._newline%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">newline</a></span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><p> </p></td></tr><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">elephant</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">new</a></span><span class="hspace"> </span><span class="RktSym">large-animal%</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._send%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">send</a></span><span class="hspace"> </span><span class="RktSym">elephant</span><span class="hspace"> </span><span class="RktSym">eat</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">new</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528def._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._object%7E25%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">object%</a></span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktOut">Nom nom nom</span></p></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._get-field%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">get-field</a></span><span class="hspace"> </span><span class="RktSym">size</span><span class="hspace"> </span><span class="RktSym">elephant</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktErr">animal%: broke its own contract</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">promised: positive/c</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">produced: 'large</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">in: the size field in</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">(class/c</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">(eat</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">(->m</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">(object/c (field (size positive/c)))</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">void?))</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">(field (size positive/c)))</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">contract from: (definition animal%)</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">blaming: (definition animal%)</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">(assuming the contract is correct)</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">at: eval:31:0</span></p></td></tr></table></td></tr></table></blockquote><h5 x-source-module="(lib "scribblings/guide/guide.scrbl")" x-source-pkg="racket-doc" x-part-tag=""Internal_Class_Contracts"">13.9.2<tt> </tt><a name="(part._.Internal_.Class_.Contracts)"></a>Internal Class Contracts</h5><p>Notice that retrieving the <span class="RktSym">size</span> field from the object
|
|
<span class="RktSym">elephant</span> blames <span class="RktSym">animal%</span> for the contract violation.
|
|
This blame is correct, but unfair to the <span class="RktSym">animal%</span> class,
|
|
as we have not yet provided it with a method for protecting itself from
|
|
subclasses. To this end we add internal class contracts, which
|
|
provide directives to subclasses for how they may access and override
|
|
features of the superclass. This distinction between external and internal
|
|
class contracts allows for weaker contracts within the class hierarchy, where
|
|
invariants may be broken internally by subclasses but should be enforced
|
|
for external uses via instantiated objects.</p><p>As a simple example of what kinds of protection are available, we provide
|
|
an example aimed at the <span class="RktSym">animal%</span> class that uses all the applicable
|
|
forms:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=Object_and_Class_Contracts.html%23%2528form._%2528%2528lib._racket%252Fclass..rkt%2529._class%252Fc%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class/c</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._field%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">field</a></span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">size</span><span class="hspace"> </span><span class="RktSym">positive/c</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._inherit-field%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">inherit-field</a></span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">size</span><span class="hspace"> </span><span class="RktSym">positive/c</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">eat</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=Object_and_Class_Contracts.html%23%2528form._%2528%2528lib._racket%252Fclass..rkt%2529._-%7E3em%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span>m</a></span><span class="hspace"> </span><span class="RktSym">edible/c</span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=void.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._void%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">void?</a></span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._inherit%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">inherit</a></span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">eat</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=Object_and_Class_Contracts.html%23%2528form._%2528%2528lib._racket%252Fclass..rkt%2529._-%7E3em%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span>m</a></span><span class="hspace"> </span><span class="RktSym">edible/c</span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=void.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._void%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">void?</a></span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._super%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">super</a></span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">eat</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=Object_and_Class_Contracts.html%23%2528form._%2528%2528lib._racket%252Fclass..rkt%2529._-%7E3em%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span>m</a></span><span class="hspace"> </span><span class="RktSym">edible/c</span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=void.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._void%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">void?</a></span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._override%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">override</a></span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">eat</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=Object_and_Class_Contracts.html%23%2528form._%2528%2528lib._racket%252Fclass..rkt%2529._-%7E3em%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span>m</a></span><span class="hspace"> </span><span class="RktSym">edible/c</span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=void.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._void%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">void?</a></span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p>This class contract not only ensures that objects of class <span class="RktSym">animal%</span>
|
|
are protected as before, but also ensure that subclasses of <span class="RktSym">animal%</span>
|
|
only store appropriate values within the <span class="RktSym">size</span> field and use
|
|
the implementation of <span class="RktSym">size</span> from <span class="RktSym">animal%</span> appropriately.
|
|
These contract forms only affect uses within the class hierarchy, and only
|
|
for method calls that cross the contract boundary.</p><p>That means that <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._inherit%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">inherit</a></span> will only affect subclass uses of a method
|
|
until a subclass overrides that method, and that <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._override%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">override</a></span> only
|
|
affects calls from the superclass into a subclass’s overriding implementation
|
|
of that method. Since these only affect internal uses, the <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._override%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">override</a></span>
|
|
form does not automatically enter subclasses into obligations when objects of
|
|
those classes are used. Also, use of <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._override%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">override</a></span> only makes sense, and
|
|
thus can only be used, for methods where no Beta-style augmentation has taken
|
|
place. The following example shows this difference:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=attaching-contracts-to-values.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fregion..rkt%2529._define%252Fcontract%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/contract</a></span><span class="hspace"> </span><span class="RktSym">sloppy-eater%</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=Object_and_Class_Contracts.html%23%2528form._%2528%2528lib._racket%252Fclass..rkt%2529._class%252Fc%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class/c</a></span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">eat</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=Object_and_Class_Contracts.html%23%2528form._%2528%2528lib._racket%252Fclass..rkt%2529._-%7E3em%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span>m</a></span><span class="hspace"> </span><span class="RktSym">edible/c</span><span class="hspace"> </span><span class="RktSym">edible/c</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=begin.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._begin%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">begin</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=attaching-contracts-to-values.html%23%2528form._%2528%2528lib._racket%252Fcontract%252Fregion..rkt%2529._define%252Fcontract%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/contract</a></span><span class="hspace"> </span><span class="RktSym">glutton%</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=Object_and_Class_Contracts.html%23%2528form._%2528%2528lib._racket%252Fclass..rkt%2529._class%252Fc%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class/c</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._override%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">override</a></span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">eat</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=Object_and_Class_Contracts.html%23%2528form._%2528%2528lib._racket%252Fclass..rkt%2529._-%7E3em%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x"><span class="nobreak">-></span>m</a></span><span class="hspace"> </span><span class="RktSym">edible/c</span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=void.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._void%7E3f%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">void?</a></span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span><span class="hspace"> </span><span class="RktSym">animal%</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._super-new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">super-new</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._inherit%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">inherit</a></span><span class="hspace"> </span><span class="RktSym">eat</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Fpublic%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/public</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">gulp</span><span class="hspace"> </span><span class="RktSym">food-list</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=for.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._for%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">for</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">f</span><span class="hspace"> </span><span class="RktSym">food-list</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">eat</span><span class="hspace"> </span><span class="RktSym">f</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._class%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">class</a></span><span class="hspace"> </span><span class="RktSym">glutton%</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._super-new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">super-new</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._inherit-field%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">inherit-field</a></span><span class="hspace"> </span><span class="RktSym">size</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._define%252Foverride%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define/override</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">eat</span><span class="hspace"> </span><span class="RktSym">f</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=let.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fletstx-scheme..rkt%2529._let%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">let</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">food-size</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._get-field%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">get-field</a></span><span class="hspace"> </span><span class="RktSym">size</span><span class="hspace"> </span><span class="RktSym">f</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=set_.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._set%2521%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">set!</a></span><span class="hspace"> </span><span class="RktSym">size</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=generic-numbers.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._%252F%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">/</a></span><span class="hspace"> </span><span class="RktSym">food-size</span><span class="hspace"> </span><span class="RktVal">2</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._set-field%2521%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">set-field!</a></span><span class="hspace"> </span><span class="RktSym">size</span><span class="hspace"> </span><span class="RktSym">f</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=generic-numbers.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._%252F%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">/</a></span><span class="hspace"> </span><span class="RktSym">food-size</span><span class="hspace"> </span><span class="RktVal">2</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">f</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">pig</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">new</a></span><span class="hspace"> </span><span class="RktSym">sloppy-eater%</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">slop1</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">new</a></span><span class="hspace"> </span><span class="RktSym">animal%</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">slop2</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">new</a></span><span class="hspace"> </span><span class="RktSym">animal%</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">slop3</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=objcreation.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._new%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">new</a></span><span class="hspace"> </span><span class="RktSym">animal%</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._send%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">send</a></span><span class="hspace"> </span><span class="RktSym">pig</span><span class="hspace"> </span><span class="RktSym">eat</span><span class="hspace"> </span><span class="RktSym">slop1</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">(object:animal% ...)</span></p></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._get-field%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">get-field</a></span><span class="hspace"> </span><span class="RktSym">size</span><span class="hspace"> </span><span class="RktSym">slop1</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">5</span></p></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=ivaraccess.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._send%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">send</a></span><span class="hspace"> </span><span class="RktSym">pig</span><span class="hspace"> </span><span class="RktSym">gulp</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._list%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktSym">slop1</span><span class="hspace"> </span><span class="RktSym">slop2</span><span class="hspace"> </span><span class="RktSym">slop3</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktErr">eat: contract violation</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">expected: void?</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">given: (object:animal% ...)</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">in: the range of</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">the eat method in</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">(class/c</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">(override (eat</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">(->m</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">(object/c</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">(field (size positive/c)))</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">void?))))</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">contract from: (definition glutton%)</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">contract on: glutton%</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">blaming: (definition sloppy-eater%)</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">(assuming the contract is correct)</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">at: eval:47:0</span></p></td></tr></table></blockquote><p>In addition to the internal class contract forms shown here, there are
|
|
similar forms for Beta-style augmentable methods. The <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._inner%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">inner</a></span>
|
|
form describes to the subclass what is expected from augmentations of
|
|
a given method. Both <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._augment%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">augment</a></span> and <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._augride%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">augride</a></span> tell the
|
|
subclass that the given method is a method which has been augmented and
|
|
that any calls to the method in the subclass will dynamically
|
|
dispatch to the appropriate implementation in the superclass. Such
|
|
calls will be checked according to the given contract. The two forms
|
|
differ in that use of <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._augment%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">augment</a></span> signifies that subclasses can
|
|
augment the given method, whereas use of <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._augride%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">augride</a></span> signifies that
|
|
subclasses must override the current augmentation instead.</p><p>This means that not all forms can be used at the same time. Only one of the
|
|
<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._override%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">override</a></span>, <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._augment%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">augment</a></span>, and <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._augride%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">augride</a></span> forms can be used
|
|
for a given method, and none of these forms can be used if the given method
|
|
has been finalized. In addition, <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._super%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">super</a></span> can be specified for a given
|
|
method only if <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._augride%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">augride</a></span> or <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._override%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">override</a></span> can be specified.
|
|
Similarly, <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._inner%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">inner</a></span> can be specified only if <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._augment%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">augment</a></span> or
|
|
<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=createclass.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fclass-internal..rkt%2529._augride%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">augride</a></span> can be specified.</p><div class="navsetbottom"><span class="navleft"><form class="searchform"><input class="searchbox" id="searchbox" type="text" tabindex="1" placeholder="...search manuals..." title="Enter a search string to search the manuals" onkeypress="return DoSearchKey(event, this, "8.6", "../");"/></form> <a href="https://download.racket-lang.org/releases/8.6/doc/index.html" title="up to the documentation top" data-pltdoc="x" onclick="return GotoPLTRoot("8.6");">top</a><span class="tocsettoggle"> <a href="javascript:void(0);" title="show/hide table of contents" onclick="TocsetToggle();">contents</a></span></span><span class="navright"> <a href="match.html" title="backward to "12 Pattern Matching"" data-pltdoc="x">← prev</a> <a href="index.html" title="up to "The Racket Guide"" data-pltdoc="x">up</a> <a href="units.html" title="forward to "14 Units (Components)"" data-pltdoc="x">next →</a></span> </div></div></div><div id="contextindicator"> </div></body></html> |