VaKeR CYBER ARMY
Logo of a company Server : Apache/2.4.41 (Ubuntu)
System : Linux absol.cf 5.4.0-198-generic #218-Ubuntu SMP Fri Sep 27 20:18:53 UTC 2024 x86_64
User : www-data ( 33)
PHP Version : 7.4.33
Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Directory :  /usr/share/doc/gnustep-base-doc/Base/ProgrammingManual/gs-base/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : //usr/share/doc/gnustep-base-doc/Base/ProgrammingManual/gs-base/Classes.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- Created by GNU Texinfo 6.7, http://www.gnu.org/software/texinfo/ -->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Classes (Objective-C GNUstep Base Programming Manual)</title>

<meta name="description" content="Classes (Objective-C GNUstep Base Programming Manual)">
<meta name="keywords" content="Classes (Objective-C GNUstep Base Programming Manual)">
<meta name="resource-type" content="document">
<meta name="distribution" content="global">
<meta name="Generator" content="makeinfo">
<link href="index.html" rel="start" title="Top">
<link href="Make.html" rel="index" title="Make">
<link href="index.html#SEC_Contents" rel="contents" title="Table of Contents">
<link href="index.html" rel="up" title="Top">
<link href="Advanced-Messaging.html" rel="next" title="Advanced Messaging">
<link href="Objects.html" rel="prev" title="Objects">
<style type="text/css">
<!--
a.summary-letter {text-decoration: none}
blockquote.indentedblock {margin-right: 0em}
div.display {margin-left: 3.2em}
div.example {margin-left: 3.2em}
div.lisp {margin-left: 3.2em}
kbd {font-style: oblique}
pre.display {font-family: inherit}
pre.format {font-family: inherit}
pre.menu-comment {font-family: serif}
pre.menu-preformatted {font-family: serif}
span.nolinebreak {white-space: nowrap}
span.roman {font-family: initial; font-weight: normal}
span.sansserif {font-family: sans-serif; font-weight: normal}
ul.no-bullet {list-style: none}
-->
</style>


</head>

<body lang="en">
<span id="Classes"></span><div class="header">
<p>
Next: <a href="Advanced-Messaging.html" accesskey="n" rel="next">Advanced Messaging</a>, Previous: <a href="Objects.html" accesskey="p" rel="prev">Objects</a>, Up: <a href="index.html" accesskey="u" rel="up">Top</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Make.html" title="Index" rel="index">Index</a>]</p>
</div>
<hr>
<span id="Writing-New-Classes"></span><h2 class="chapter">4 Writing New Classes</h2>
<span id="index-writing-new-classes"></span>


<p>Objective-C class definitions are always divided into two parts: an
<i>interface</i> and an <i>implementation</i>.  This division mirrors the common C
library division into a header file with function declarations, which is
distributed to all users of a library, and a source file with the
implementations, which is only used to compile the library and is generally
not distributed to users.  A class interface declares instance variables,
methods and the superclass name, while the implementation file holds the
operational code that implements those methods.  Typically the interface and
implementation are held in separate files, using the <code>.h</code> and <code>.m</code>
extensions, respectively. They may, however, be merged into one file, and a
single file may implement many classes.
</p>

<span id="Interface"></span><h3 class="section">4.1 Interface</h3>
<span id="index-interface"></span>

<p>The interface is included in the source using <code>#include</code>:
</p>
<div class="example">
<pre class="example">#include &quot;SomeClass.h&quot;
</pre></div>

<p>To ensure that a Header file is included only once, it is usual to
protect it with pre-compiler defines:
</p>
<div class="example">
<pre class="example">#ifndef _MY_CLASS_H_INCLUDED
#define _MY_CLASS_H_INCLUDED

/* HEADER FILE */
#endif
</pre></div>

<p>This is the standard C technique to protect header files from being included
more than once.  A cleaner alternative, introduced in Objective-C, is to use
the <code>#import</code> directive instead of <code>#include</code>.  The compiler will
automatically include <code>#import</code>ed files no more than once, even if
multiple <code>import</code> statements are encountered.  Thus, you can do away
with the messy preprocessor conditionals in the header file.
</p>
<p>You should be careful, however, to only use <code>#import</code> for Objective-C
interface headers, and continue using <code>#include</code> for standard C files.
It is possible, though not likely, that regular C headers may rely on being
included multiple times in some cases.  Also, you may need to include the
compiler directive <code>-Wno-import</code> to gcc to avoid a didactic warning to
this effect.
</p>

<span id="Interface-Capabilities"></span><h4 class="subsection">4.1.1 Interface Capabilities</h4>

<p>The interface file declares new classes that can be used by
source code, holding all the information necessary to use the
classes from other Objective-C code. Firstly, the file reveals
to the programmer the position of the class in the class hierarchy
by defining exactly which is the superclass. Secondly, it informs
programmers of what variables are inherited when they create subclasses.
Finally, the interface file may inform other software entities
of the messages that can be sent to the class object and to the
instances of the class. 
</p>
<p>Interface files use the <code>.h</code> extension as for ordinary C header files.
(If you use emacs, put a line &ldquo;<code>// -*-ObjC-*-</code>&rdquo; at the top of your file
to use the correct mode.)
</p>
<p>Here is an example of a class interface declaration:
</p>
<div class="example">
<pre class="example">#import &lt;Foundation/NSObject.h&gt;

@interface Point : NSObject
{
@private
    // instance variables only accessible to instances of this class ...
@protected
    // instance variables accessible to instances of this class or subclasses
  float x;
  float y;
@public
    // instance variables accessible by all code ...
}

// class methods
+ (id) new;
+ (id) newWithX: (float)x0 Y: (float)y0;
+ (Point*) point;
+ (Point*) pointWithX: (float)x0 Y: (float)y0;

// instance methods
- (id) init;
- (id) initWithX: (float)x0 Y: (float)y0;
- (float) x;  // (field accessor)
- (float) y;
- (void) setX: (float)newX;
- (void) setY: (float)newY;
@end
</pre></div>

<ul>
<li> The interface file should import the interface of the superclass of the class
it is defining.

</li><li> The interface is enclosed between the compiler directives
<code>@interface</code> and <code>@end</code>.

</li><li> <code>@interface Point : Object</code> names the class
and links it to the superclass.  If no superclass is named, and the
directive is without a colon, the compiler assumes that a root class
is being created.  You more than likely don&rsquo;t want to do this.

</li><li> Braces enclose declared instance variables; each class&rsquo;s instance will
have all these instance variables including instance variables
inherited from the superclass, and from the superclass of the
superclass, extending to the root class.

</li><li> Instance variables may be declared as <code>private</code>, <code>protected</code>, or
<code>public</code>.  An instance&rsquo;s <i>private</i> variables may only be accessed by
instances of this class.  An instance&rsquo;s <i>protected</i> variables may be
accessed by instances of this class or instances of subclasses of this class.
<i>Public</i> variables may be accessed by any code.  This is analogous to the
usage in C++ and Java.  If you do not mark your instance variable declaration
explicitly, it is made <code>protected</code> by default.

</li><li> Method declarations that begin with a &quot;+&quot; sign are class methods, and are
defined for the class object.  Thus, you can call them without creating an
instance, and their implementations do not have access to any instance
variables.  A class object inherits class methods from superclasses.

</li><li> Method declarations that begin with a &quot;-&quot; sign are instance methods,
and are defined for class instances.  Class instances inherit instance
methods from superclasses.

</li><li> A method may share the name of an instance variable. 

</li><li> A method return type is declared using the C syntax for type casts:
<div class="example">
<pre class="example">- (float) x;
</pre></div>
<p>which is a method returning a float.
</p>
</li><li> Argument types can be declared in the same way as method return types:
<div class="example">
<pre class="example">- (void) setX: (float)newX;
</pre></div>
<p>which is a method that returns nothing, and takes a single float as
its argument.
</p>
<p>Note. The default type for methods and messages (<code>id</code>) is assumed
when a return or argument type is not explicitly declared.
For example, &rsquo;<code>-name</code>&rsquo; implicitly means a method returning <code>id</code>
(i.e. an object). It is usually better to avoid this and use
explicit typing as in
</p><div class="example">
<pre class="example">- (NSString*) name;
</pre></div>

</li></ul>

<span id="Including-Interfaces"></span><h4 class="subsection">4.1.2 Including Interfaces</h4>
<p>Source code (including Objective-C implementation and interface files) may
integrate interfaces using <code>#import</code> (or <code>#include</code>).  Thereafter
the source module may utilize the classes in those interfaces so as to:
</p>
<ul>
<li> Make instances of them.

</li><li> Send messages to invoke methods declared for them.

</li><li> Refer to instance variables in them.

</li></ul>

<p>With the exception of the root class, all working interfaces integrate a
superclass using either <code>#import</code> or <code>#include</code> &ndash; as was seen in
the previous simplified interface file example.  As a result the vast majority
of class files begin with a standard form that includes their superclasses,
and thus places them in the class hierarchy:
</p>
<div class="example">
<pre class="example">#import &quot;SomeSuperclass.h&quot;

@interface SomeClass : SomeSuperclass
{
  // instance variables ...
}
  // method declarations ...
@end
</pre></div>


<span id="Referring-to-Classes-_002d-_0040class"></span><h4 class="subsection">4.1.3 Referring to Classes - @class</h4>

<p>It is possible for a source module to refer to classes without including their
interface files. This is useful when you just need to tell the compiler that a
certain word is a class name, but you want to avoid the overhead of including
the whole interface file for that class.
</p>
<p>For example, to inform the compiler that <code>Border</code> and <code>Square</code> are
classes without including their full interface file, the following syntax is
used:
</p>
<p><code>@class Border, Square;</code>
</p>
<p>Class names may also appear in interface files at times when
instance variables, return values and arguments are statically typed:
</p>
<div class="example">
<pre class="example">#import &quot;Foundation/NSObject.h&quot;

@class Point

@interface Square : NSObject
{
@protected
  Point *lowerLeft;
  float sideLength;
}
+ (id) newWithLowerLeft: (Point *)lowerLeft sideLength: (float)sideLength;

- (id) initWithLowerLeft: (Point *)lowerLeft sideLength: (float)sideLength;

- (Point *) lowerLeft;
- (float) sideLength;
- (void) setLowerLeft: (Point *)newLowerLeft;
- (void) setSideLength: (float)newSideLength;
@end
</pre></div>

<p>Here, we see the <code>Point</code> class we declared earlier being used as a
component in <code>Square</code>&rsquo;s definition.  Because this class is only referred
to here to declare variables and method signatures, it suffices to reference
it only using the <code>@class</code> directive.  On the other hand, the
implementation file may need to send messages to <code>Point</code> instances and
would be better of importing the interface in this case.
</p>
<p>The compiler will produce a warning if you don&rsquo;t include it, and no type
checking can be performed (to see if class instances respond to the messages
you send to them), but compilation will succeed.  It is best to take advantage
of type-checking when you can, however, and include interfaces that messages
are to be sent to.
</p>
<p>There is one situation where you <i>must</i> include the interface however.  If
you are implementing a new class, you always need to include the interface of
the superclass; <code>@class</code> cannot be used in this case because the
compiler needs to know the details of the superclass and its instance
variables etc., so as to create a fully working new class.  If you try using
<code>@class</code> in this situation, compilation will abort.
</p>

<span id="Implementation"></span><h3 class="section">4.2 Implementation</h3>

<p>An interface file declares a class, while an implementation file
implements it. The separation between the interface and
implementation file yields a black box concept where the programmer
using the class need only be concerned with the interface and its
declared methods, superclasses, and instance variables.
The implementation of classes is transparent to the programmer
who may use them without detailed knowledge of their structures. 
</p>
<p>Implementation files use the <code>.m</code> extension, to distinguish them from
ordinary C files.
</p>

<span id="Writing-an-Implementation"></span><h4 class="subsection">4.2.1 Writing an Implementation</h4>

<p>An implementation file contents are encapsulated between
<code>@implementation</code> and <code>@end</code> directives:
</p>
<div class="example">
<pre class="example">#import &quot;Point.h&quot;
@implementation Point
// method implementations
+ (id)new
{
  // statements ...
}

+ (id)newWithX: (float)x Y: (float)y
{
  // statements ...
}

// ...

- (void)setY: (float)newY
{
  // statements ...
}

@end
</pre></div>

<p>The implementation file uses <code>#import</code> to include a named interface file
holding all declarations.  Then it places method implementations for the class
between <code>@implementation</code> and <code>@end</code> directives.  Each method
declared in the interface must be implemented.  Instance variables may be
referred to in instance methods (the ones with a &ldquo;-&rdquo; in front of them) but
not class methods (the ones with a &ldquo;+&rdquo;).
</p>
<div class="example">
<pre class="example">- (float) x
{
  return x;
}

- (void) setX: (float)newX
{
  x = newX;
}
</pre></div>


<span id="Super-and-Self"></span><h4 class="subsection">4.2.2 Super and Self</h4>

<p>To assist in writing instance methods, Objective-C provides the two reserved
words <b><code>self</code></b> and <b><code>super</code></b>.  <code>Self</code> is used to refer to
the current instance, and is useful for, among other things, invoking other
methods on the instance:
</p>
<div class="example">
<pre class="example">- (Foo *) foo
{
  if (![self fooIsInitialized])
    [self initializeFoo];
  return foo;
}
</pre></div>

<p><code>Super</code> is used to refer to method implementations in the superclass of
the instance.  It is useful when overriding methods and when writing
initializers, as discussed in the next section.
</p>

<span id="Instance-Initialization"></span><h4 class="subsection">4.2.3 Instance Initialization</h4>

<p>Instance initialization is one of the trickier aspects of getting started in
Objective-C.  Recall that instances of a class are created by use of the class
<code>alloc</code> method (inherited from <code>NSObject</code>) but are initialized by
instance methods.  This works a little differently than in C++ and Java, where
constructors are special methods that are neither class nor instance methods.
In particular, since initializer methods are inherited instance methods, they
may still be called even if you have not implemented them in your class.  For
example, it is always valid to invoke
</p>
<div class="example">
<pre class="example">SomeComplexClass *c = [[SomeComplexClass alloc] init];
</pre></div>

<p>Even if you have not implemented <code>init</code> in <code>SomeComplexClass</code>, the
superclass&rsquo;s implementation will be invoked, or, ultimately,
<code>NSObject</code>&rsquo;s if no other ancestors implement it.  Obviously, this could
result in some of <code>SomeComplexClass</code>&rsquo;s internal state being left
uninitialized.  For this reason, you should always either provide an
<code>init</code> implementation, or document whether it should be used.  We will
return to this concern below.
</p>
<p>Typically, a class will also provide one or more <code>initWith...</code> methods
for initialization with arguments, and it may optionally also provide
<code>+new</code> methods and convenience class methods that act like constructors.
The general approach
to implementing these is illustrated here for the <code>Point</code> class.
</p>
<div class="example">
<pre class="example">+ new
{
  Point *point;

  // note &quot;self&quot; refers to the &quot;Point&quot; _class_ object!
  point = [[self allocWithZone: NSDefaultMallocZone()] init];
  return point;
}

+ newWithX: (float)x0 Y: (float)y0
{
  Point *point;

  point = [[self allocWithZone: NSDefaultMallocZone()] initWithX: x Y: y];
  return point;
}

+ point
{
  Point *point;

  // note &quot;self&quot; refers to the &quot;Point&quot; _class_ object!
  point = [self new];
  return AUTORELEASE(point);
}

+ pointWithX: (float)x0 Y: (float)y0
{
  Point *point;

  point = [self newWithX: x Y: y];
  return AUTORELEASE(point);
}

- init
{
  return [self initWithX: 0.0 Y: 0.0];
}

// this is the &quot;designated&quot; initializer
- initWithX: (float)x0 Y: (float)y0
{
  self = [super init];
  if (self != nil)
    {
      x = x0;
      y = y0;
    }
  return self;
}
</pre></div>

<p>Notice that, first, the convenience constructors (<code>new</code> and
<code>newWithX:Y:</code>) execute <code>[self allocWithZone:]</code> to begin with.  The
&ldquo;<code>self</code>&rdquo; here refers to the <i>class</i> object, since it is used inside a
<i>class</i> method.  Thus the effect is the same as if &ldquo;<code>[Point alloc]</code>&rdquo;
had been executed in external code.  Second, notice that the other
convenience constructors (<code>point</code> and <code>pointWithX:Y:</code>)
autorelease the new instance before returning it.
This is to follow the rules of memory
management discussed in <a href="Objects.html">Memory Management</a>.  Third,
note that the <code>new..</code>  methods each call a corresponding <code>init...</code>
method.  It is not necessary to maintain such a one to one correspondence but
it is a common convention to have the convenience implementations rely on
instance <code>init</code> methods as shown.  Fourth, note that the use of
<code>[self allocWithZone: NSDefaultMallocZone()]</code> rather than
<code>[self alloc]</code> is generally unnecessary, but provides a slight
efficiency gain since <code>+alloc</code> is implemented by calling
<code>+allocWithZone:</code> on the default zone.
</p>
<p><b>Designated Initializer</b>
</p>
<p>Finally, notice that the <code>initWithX:Y:</code> method is marked as the
&ldquo;designated&rdquo; initializer.  This concept is important to ensure proper
initialization for classes within a hierarchy.  The designated initializer
should be the one with the most control over the nature of the new instance,
and should be the one that all other initializers &ldquo;ground out&rdquo; in.  In
other words, all other initializers should be chained so that they either
call the designated initializer, or they call another initializer that
(eventually) calls it.
</p>
<p>The importance of having a designated initializer is this: when a subclass is
created, it need only override the designated initializer to ensure that all
of its instances are properly initialized.  If this is not done, external
code could invoke an initializer that initializes only the superclass&rsquo;s
instance variables, and not the subclass&rsquo;s.  To avoid this, each class
designates a &ldquo;ground out&rdquo; initializer to which other initializers
ultimately delegate.  Then the subclass overrides this initializer, and in
its own designated initializer, makes a call to it, to ensure that the
superclass is initialized properly.  Thus:
</p>
<div class="example">
<pre class="example">@implementation SuperClass
- initWithA: (int)a
{
  return [self initWithA:a B:0];  // 0 is default value
}

// designated init for SuperClass
- initWithA: (int)a B: (int)b
{
  self = [super init];
  myA = a;
  myB = b;
  return self;
}
@end

@implementation SubClass

// overrides SuperClass's designated init
- initWithA: (int)a B: (int)b
{
  return [self initWithA: (int)a B: (int)b C: (int)c];
}

// designated init for SubClass
- initWithA: (int)a B: (int)b C: (int)c
{
  self = [super initWithA: a B: b];
  myC = c;
  return self;
}
@end
</pre></div>

<p>Note, as shown above, unlike in some other object-oriented languages,
&rsquo;<code>self</code>&rsquo; is a variable that can be redefined.  For example, we could have
written the <code>new</code> constructor above like this:
</p>
<div class="example">
<pre class="example">{
  self = [[self alloc] init];
    // note &quot;self&quot; now refers to the new instance!
  [self setX: 1.0];
  return self;
}
</pre></div>

<p>Another point to note is that Objective-C does not enforce calling superclass
initializers before carrying out subclass initialization.  Although above the
first call in the designated initializer was always <code>[super ...]</code>, this
was not required, and if you need to set something up before <code>super</code>
acts, you are free to do so.
</p>

<span id="Flexible-Initialization"></span><h4 class="subsection">4.2.4 Flexible Initialization</h4>

<p>As mentioned before, it is possible for an initialization process to, if
desired, return not a new object but an existing object.  This may be done in
one of two ways.  If you are doing it from a convenience class method like
<code>new</code>, then use something like the following:
</p>
<div class="example">
<pre class="example">+ new
{
  if (singleton == nil)
    singleton = [[self alloc] init];
  return singleton;
}
</pre></div>

<p>Note this example presupposes the existence of a class variable,
&rsquo;<code>singleton</code>&rsquo;.  Class variables as such don&rsquo;t exist in Objective-C but
can be simulated, as discussed below.
</p>
<p>If you want to possibly return an existing instance from an init instance
method like <code>init</code>, the procedure is slightly more complicated:
</p>
<div class="example">
<pre class="example">- init
{
  if (singleton != nil)
    {
      RELEASE(self);
      self = RETAIN(singleton);
    }
    else
    {
      singleton = self;
    }
  return self;
}
</pre></div>

<p>Here, we explicitly <b>deallocate</b> the current instance and replace it with
the desired existing instance.  Because this might happen, you should always
be careful to use the returned value from an <code>init</code> method:
</p>
<div class="example">
<pre class="example">id anObject = [SomeClass alloc];
  // this is bad:
[anObject init];
  // anObject might have been deallocated!
  // do this instead:
anObject = [anObject init];
</pre></div>

<p>One scenario where this actually occurs in the GNUstep libraries is with the
class <code>NSConnection</code>.  It only permits one connection to exist
between any two ports, so if you call <code>initWithReceivePort:sendPort:</code>
when a connection for the ports exists, the method will deallocate
the newly allocated instance, and return the current conflicting object,
rather than the receiver.
</p>
<p>In general, it is better to catch this type of requirement in a &ldquo;<code>new</code>&rdquo;
class method rather than an instance &ldquo;<code>init</code>&rdquo; method so as to avoid
the unnecessary allocation of instances that will not be used, however this
is not always possible given other design constraints.
</p>

<span id="Instance-Deallocation"></span><h4 class="subsection">4.2.5 Instance Deallocation</h4>

<p>As described in <a href="Objects.html">Memory Management</a>,
objects should be deallocated when they are no longer needed.  When garbage
collection is not being used, this is done through explicit calls to the
<code>dealloc</code> method.  When GC <i>is</i> being used, <code>dealloc</code> is still
called implicitly, and should be implemented.  However the tasks of the
<code>dealloc</code> method are fewer in this case.
</p>
<p>When garbage collection is <i>not</i> active, the <code>dealloc</code> method must
release all other objects that this instance has retained.  Usually these are
those instance variables that are objects rather than primitive types.  In
certain cases such as container classes, other objects must be released as
well.  In addition, if the instance has acquired any external resources, such
as a network connection or open file descriptor, these should be relinquished
as well.  Likewise, any memory that has been directly allocated through use
of <code>malloc</code> or other functions should be released.
</p>
<p>When garbage collection <i>is</i> active, the <code>dealloc</code> method is still
responsible to relinquish external resources, but other GNUstep objects need
not be released, since they will be garbage collected once this instance has
been.
</p>
<p>If you cannot be sure whether your class will be running in a
garbage-collecting environment, it never hurts to execute all of the releases
of other objects.  This will not harm the operation of the garbage collector,
though it will result in pointless calls to the retain/release methods that
are stubbed out under garbage collection.  If this could cause a performance
hit in your application, you should use the RETAIN/RELEASE macros instead of
the function calls.
</p>
<p>Here is an example of a <code>dealloc</code> implementation:
</p>
<div class="example">
<pre class="example">- dealloc
{
  RELEASE(anInstanceVariableObject);
  NSZoneFree(NULL, myMemory);
  [super dealloc];
}
</pre></div>

<p>Here, we use the <code>RELEASE</code> macro to release an instance variable, and the
<code>NSZoneFree</code> function to free memory that was earlier allocated with
<code>NSZoneMalloc</code> or a related function.  (See <a href="Base-Library.html">Base Library</a> for
discussion of GNUstep&rsquo;s raw memory allocation functions.)  The <code>NULL</code>
used indicates that the memory was from the default zone, and is equivalent
to saying &rsquo;<code>NSDefaultMallocZone()</code>&rsquo; instead.
</p>
<p>Finally, notice we end with a call to <code>[super dealloc]</code>.  This should
always be done in <code>dealloc</code> implementations, and you should never
concern yourself with deallocating structures that are associated with a
superclass, since it will take care of this itself.
</p>

<span id="Protocols"></span><h3 class="section">4.3 Protocols</h3>
<span id="index-protocols"></span>
<span id="index-protocols_002c-formal"></span>

<p>Protocols in Objective-C provide a level of flexibility beyond class
structure in determining what messages objects respond to.  They are similar
to interfaces in Java but more flexible.
</p>
<p>There are two types of protocol in Objective-C: <b>informal</b> protocols, where
we document methods to which objects will respond, and specify how they should
behave, and <b>formal</b> protocols, where we provide a list of methods that an
object will support in a format where the compiler can check things, and the
runtime can also check that an object conforms to the protocol.  Informal
protocols are merely convention, but are useful where we want to say that some
system will work as long as it (or its delegate) implements some subset of a
group of methods.  Formal protocols are of more use when we want the compiler
or runtime to check that an object implements all of a group of methods
itself.  Formal protocols form an inheritance hierarchy like classes, and a
given class may conform to more than one protocol.  Thus, formal protocols are
identical in many respects to Java <i>interfaces</i>.
</p>
<p>As in Java, a particularly important use of protocols is in defining the
methods that an object in a remote process can respond to &hellip; by setting
the protocol used by a local proxy object, you can avoid having to send
messages to the remote process to check what methods are available - you can
simply check the local protocol object.  This will be covered later in
<a href="Distributed-Objects.html">Distributed Objects</a>.
</p>
<p>Informal protocols are closely associated with <i>Categories</i>, another
Objective-C language facility, and will be discussed in the next section.
</p>

<span id="Declaring-a-Formal-Protocol"></span><h4 class="subsection">4.3.1 Declaring a Formal Protocol</h4>

<p>A formal protocol is declared as a series of method declarations, just like a
class interface.  The difference is that a protocol declaration begins with
<code>@protocol</code> rather than <code>@interface</code>, and has an optional
<b>super</b> protocol specified in angle brackets.
</p>
<div class="example">
<pre class="example">@protocol List
- (void) add:        (id) item;
- (void) remove:     (id) item;
- getAtIndex:        (int)idx;
- (void) clear;
@end

@protocol LinkedList &lt;List&gt;
- (void) addFirst:   (id)item;
- (void) addLast:    (id)item;
- getFirst;
- getLast;
@end
</pre></div>


<span id="Implementing-a-Formal-Protocol"></span><h4 class="subsection">4.3.2 Implementing a Formal Protocol</h4>

<p>If you want your class to conform to a protocol, you declare it in your
interface, and implement the methods in your declaration:
</p>
<div class="example">
<pre class="example">@interface BiQueue &lt;LinkedList&gt;
{
  // instance variables ...
}
  // method declarations ...
  // [don't need to redeclare those for the LinkedList protocol]
- takeFirst
- takeLast
@end

...

@implementation BiQueue
  // must implement both List's and LinkedList's methods ...
- add:        (id) item
{
  // ...
}

- addFirst:   (id)item
{
  // ...
}
@end
</pre></div>

<p>To declare conformance to multiple protocols, do something like this:
</p>
<div class="example">
<pre class="example">@interface ContainerWindow &lt; List, Window &gt;
  ...
@end
</pre></div>

<p>The implementation must include all methods in both protocols.
</p>

<span id="Using-a-Formal-Protocol"></span><h4 class="subsection">4.3.3 Using a Formal Protocol</h4>

<p>To use a formal protocol, simply send objects the messages in the protocol.
If you want type-checking, you must either use the type of a class
implementing the protocol, or use a special syntax:
</p>
<div class="example">
<pre class="example">...
BiQueue queue = [[BiQueue alloc] init];
  // send a LinkedList message
[queue addFirst: anObject];

  // alternatively, we may stipulate only that an object conforms to the
  // protocol in the following way:
id&lt;LinkedList&gt; todoList = [system getTodoList];
task = [todoList getFirst];
...
</pre></div>

<p>In the last part of this example, we declare that <code>todoList</code> is an
object that conforms to the <code>LinkedList</code> protocol, but do not specify
what class it may be an instance of.
</p>
<p>If you are not sure the returned object does indeed conform to the protocol
you are interested in, you can check it:
</p>
<div class="example">
<pre class="example">if ([anObject conformsToProtocol: aProtocol] == YES)
  {
    // We can go ahead and use the object.
  }
else
  {
    NSLog(@&quot;Object of class %@ ignored ... does not conform to 
      protocol&quot;, NSStringFromClass([anObject class]));
  }
</pre></div>

<p>Finally, you can specify an object conforming to <i>multiple</i> protocols in
the same way you declare it in an interface:
</p>
<div class="example">
<pre class="example">id &lt;LinkedList, Window&gt;   windowContainerOfUnknownClass;
</pre></div>


<span id="Categories"></span><h3 class="section">4.4 Categories</h3>
<span id="index-categories"></span>

<p>Categories provide a way in Objective-C to add new methods to an existing
class, without declaring a subclass.  Once the category is declared and
implemented, all instances of the existing class that are created will include
the capability to respond to the new methods.  Furthermore, subclasses of the
class will inherit these methods.  However, it is not possible to add instance
variables to a class using a category.  Categories do not have an obvious
parallel in other major object-oriented languages (with the exception of
Ruby), but it is well worth taking the trouble to understand them and the
benefits they can provide.
</p>
<p>A category is declared in connection with the class it is going to modify.
(You can think of it as a new &ldquo;category&rdquo; of instances of this class.)
</p>
<div class="example">
<pre class="example">#import &quot;Point.h&quot;

@interface Point (Transformable)
- translateByX: (float)tx Y: (float)ty;
- rotateByAngle: (float)radians;
- scaleByAmountX: (float)xscale Y: (float)yscale;
@end
</pre></div>

<p>You then provide an implementation file more or less analogously to that for
a class, where you implement just the new methods:
</p>
<div class="example">
<pre class="example">#import &quot;PointTransformable.h&quot;

@implementation Point (Transformable)
- (void) translateByX: (float)tx Y: (float)ty
{
  x += tx;
  y += ty;
  return self;
}

- (void) rotateByAngle: (float)radians
{
  // ...
}

- (void) scaleByAmountX: (float)xscale Y: (float)yscale
{
  // ...
}
@end
</pre></div>

<p>Notice that you have access to instance variables of the class you are
creating a category of; this includes private and protected variables.
</p>
<p>One of the primary uses of categories is illustrated by this example.  Suppose
you are working with a third party drawing package that uses some geometrical
classes such as <code>Point</code> and <code>Line</code>.  You are developing an animation
program based on the package and need the ability to move things around.
Rather than employing a complex subclassing or aggregation scheme to add these
capabilities, you simply define the <code>Transformable</code> category for each of
the geometrical entities.  At runtime, all instances of these entities,
whether created by you or the package itself, have the additional methods.
The presence of these methods does not affect the existing operation of this
or any third party package, but allows you to conveniently implement the
enhanced functionality you need.
</p>

<span id="Category-Overrides"></span><h4 class="subsection">4.4.1 Category Overrides</h4>

<p>You can also use categories to override methods that a class already has.  If
you do so, you cannot access an existing implementation in the class itself,
however you can still call <code>[super someMethod]</code> to access an
implementation inherited from a superclass.  You obviously need to be careful
not to break existing functionality.
</p>
<p>You can add multiple categories to a class by declaring them and implementing
them separately.  Instances of the class will then implement <i>all</i> of the
categories declared.  The order in which the category implementations are
searched for methods is not defined, therefore you cannot override a method
implemented in one category with an implementation in another.
</p>

<span id="Categories-as-an-Implementation-Tool"></span><h4 class="subsection">4.4.2 Categories as an Implementation Tool</h4>

<p>Categories are not just useful for extending an existing class.  Another major
use for categories is to separate the implementation of a <i>new</i> class into a
number of source files.  (Each file implements one category of the new class,
and at runtime instances of the class respond to the methods in all the
categories.)  The benefits of this program development strategy include:
grouping subject-oriented methods; incremental compilation for large classes;
helping to logically divide the class when being created by a number of
developers; and, permitting configuration-specific classes targeting
particular applications.
</p>

<span id="Categories-and-Protocols"></span><h4 class="subsection">4.4.3 Categories and Protocols</h4>

<p>As described in the previous section, in addition to the <i>formal</i> protocol
facility described, Objective-C provides for <i>informal</i> protocols.  An
informal protocol is essentially a category declaration without an
implementation.  Usually, the informal protocol is declared as a category for
a high-level object, such as <code>NSObject</code>, then each class that actually
wishes to implement something in the protocol lists the methods it chooses to
implement in its interface and provides implementations in its
implementation.
</p>

<span id="Simulating-Private-and-Protected-Methods"></span><h3 class="section">4.5 Simulating Private and Protected Methods</h3>

<p>Unlike most object-oriented languages Objective-C does not provide for method
scoping.  Instead, all methods are effectively public.  Often, however, it is
useful to have internal &ldquo;utility&rdquo; methods that help a class do its job but
are hidden from external use.  Rather than cluttering up the class&rsquo;s API with
a bunch of methods marked &ldquo;do not use&rdquo;, one wants to make these methods
visible only to subclasses, or only to the class itself.  Categories can help
in this regard.
</p>
<p><b>Using Categories</b>
</p>
<p>One common approach is to define a category within a class&rsquo;s
<i>implementation</i> file:
</p>
<div class="example">
<pre class="example">

#import &quot;Point.h&quot;

@interface Point (Private)
-(BOOL) isPositiveQuadrant;
@end

@implementation Point
  // public method implementations ...
@end

@implementation Point (Private)
-(BOOL) isPositiveQuadrant
{
  return (x &gt; 0) &amp;&amp; (y &gt; 0) ? YES : NO;
}
@end
</pre></div>

<p>All of this code would appear in the file <code>Point.m</code>.  What this does is
add a category to Point defining the private methods.  Since external code
only &ldquo;knows about&rdquo; <code>Point</code> through its interface file, these additional
methods are effectively invisible.  However, you should be aware that external
code is not prevented from actually calling the private methods, if it happens
to know about them.  However the compiler will produce a warning if you try
to do this with a typed variable:
</p>
<div class="example">
<pre class="example">Point *p = [[Point alloc] init];
  // works, but produces a compile warning
BOOL b = [p isPositiveQuadrant];
</pre></div>

<p>The bright side of this is it allows you to simulate <i>protected</i> methods as
well.  For this, the writer of a subclass must be informed in some way about
the protected methods, and they will need to put up with the compiler
warnings.  Alternatively, you could declare the Protected category in a
separate interface file (e.g., &ldquo;<code>PointProtected.h</code>&rdquo;), and provide this
interface file with the understanding that it should only be imported and used
by a subclass&rsquo;s interface file.
</p>
<p><b>Using Convention</b>
</p>
<p>Another approach to providing <i>protected</i> methods that the class or subclass
can use is to prefix these methods with an underscore (&rsquo;_&rsquo;).  These methods
will still be visible publicly, but programmers will know, by convention, not
to use them externally, and the <a href="GSDoc.html">GNUstep documentation system</a> will
automatically mark these in API documentation as off-limits.
</p>
<p>An alternative approach to providing <i>private</i> methods is to simply declare
them as functions within the implementation file itself.  The catch to this is
that these functions will <i>not</i> have access to the class&rsquo;s instance
variables.  You will need to pass these in manually whenever you invoke them
from an ordinary method.
</p>

<span id="Simulating-Class-Variables"></span><h3 class="section">4.6 Simulating Class Variables</h3>

<p>While Objective-C does not provide for variables that are associated with the
class as a whole rather than an instance, these are often useful.  It is
possible to simulate them to a limited extent by declaring static variables in
the implementation file for the class (inside the <code>@implementation</code>
block).  The variables will not be available to subclasses, unless they
explicitly declare them &ldquo;<code>extern</code>&rdquo; and are compiled at the same time.
</p>






<p>...
</p>

<hr>
<div class="header">
<p>
Next: <a href="Advanced-Messaging.html" accesskey="n" rel="next">Advanced Messaging</a>, Previous: <a href="Objects.html" accesskey="p" rel="prev">Objects</a>, Up: <a href="index.html" accesskey="u" rel="up">Top</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Make.html" title="Index" rel="index">Index</a>]</p>
</div>



</body>
</html>

VaKeR 2022