Defining a Class
parentesys

Defining a Class

Much of object-oriented programming consists of writing the code for new objects—defining new classes. In Objective-C, classes are defined in two parts: An interface that declares the methods and instance variables of the class and names its superclass An implementation that actually defines the class (contains the code that implements its methods)

14 nov 2007

Much of object-oriented programming consists of writing the code for new objects—defining new classes. In Objective-C, classes are defined in two parts:

  • An interface that declares the methods and instance variables of the class and names its superclass

  • An implementation that actually defines the class (contains the code that implements its methods)

These are typically split between two files, sometimes however a class definition may span several files through the use of a feature called a “category.” Categories can compartmentalize a class definition or extend an existing one. Categories are described in “Categories and Extensions.”

Contents:

Source Files
Class Interface
Class Implementation

 

 

Source Files

Although the compiler doesn’t require it, the interface and implementation are usually separated into two different files. The interface file must be made available to anyone who uses the class.

A single file can declare or implement more than one class. Nevertheless, it’s customary to have a separate interface file for each class, if not also a separate implementation file. Keeping class interfaces separate better reflects their status as independent entities.

Interface and implementation files typically are named after the class. The name of the implementation file has the .m extension, indicating that it contains Objective-C source code. The interface file can be assigned any other extension. Because it’s included in other source files, the name of the interface file usually has the .h extension typical of header files. For example, the Rectangle class would be declared in Rectangle.h and defined in Rectangle.m.

Separating an object’s interface from its implementation fits well with the design of object-oriented programs. An object is a self-contained entity that can be viewed from the outside almost as a “black box.” Once you’ve determined how an object interacts with other elements in your program—that is, once you’ve declared its interface—you can freely alter its implementation without affecting any other part of the application.

 

Class Implementation

The definition of a class is structured very much like its declaration. It begins with the @implementation directive and ends with the @end directive:

@implementation ClassName : ItsSuperclass
{
    instance variable declarations
}
method definitions
@end

However, every implementation file must import its own interface. For example, Rectangle.m imports Rectangle.h. Because the implementation doesn’t need to repeat any of the declarations it imports, it can safely omit:

  • The name of the superclass

  • The declarations of instance variables

This simplifies the implementation and makes it mainly devoted to method definitions:

#import "ClassName.h"
 
@implementation ClassName
method definitions
@end

Methods for a class are defined, like C functions, within a pair of braces. Before the braces, they’re declared in the same manner as in the interface file, but without the semicolon. For example:

+ alloc
{
    ...
}
 
- (BOOL)isfilled
{
    ...
}
 
- (void)setFilled:(BOOL)flag
{
    ...
}

Methods that take a variable number of arguments handle them just as a function would:

#import <stdarg.h>
 
 ...
 
- getGroup:group, ...
{
    va_list ap;
    va_start(ap, group);
    ...
}

In this section:

Referring to Instance Variables
The Scope of Instance Variables


 

Referring to Instance Variables

By default, the definition of an instance method has all the instance variables of the object within its scope. It can refer to them simply by name. Although the compiler creates the equivalent of C structures to store instance variables, the exact nature of the structure is hidden. You don’t need either of the structure operators (. or ->) to refer to an object’s data. For example, the following method definition refers to the receiver’s filled instance variable:

- (void)setFilled:(BOOL)flag
{
    filled = flag;
    ...
}

Neither the receiving object nor its filled instance variable is declared as an argument to this method, yet the instance variable falls within its scope. This simplification of method syntax is a significant shorthand in the writing of Objective-C code.

When the instance variable belongs to an object that’s not the receiver, the object’s type must be made explicit to the compiler through static typing. In referring to the instance variable of a statically typed object, the structure pointer operator (->) is used.

Suppose, for example, that the Sibling class declares a statically typed object, twin, as an instance variable:

@interface Sibling : NSObject
{
    Sibling *twin;
    int gender;
    struct features *appearance;
}

As long as the instance variables of the statically typed object are within the scope of the class (as they are here because twin is typed to the same class), a Sibling method can set them directly:

- makeIdenticalTwin
{
    if ( !twin ) {
        twin = [[Sibling alloc] init];
        twin->gender = gender;
        twin->appearance = appearance;
    }
    return twin;
}

The Scope of Instance Variables

Although they’re declared in the class interface, instance variables are more a matter of the way a class is implemented than of the way it’s used. An object’s interface lies in its methods, not in its internal data structures.

Often there’s a one-to-one correspondence between a method and an instance variable, as in the following example:

- (BOOL)isFilled
{
    return filled;
}

But this need not be the case. Some methods might return information not stored in instance variables, and some instance variables might store information that an object is unwilling to reveal.

As a class is revised from time to time, the choice of instance variables may change, even though the methods it declares remain the same. As long as messages are the vehicle for interacting with instances of the class, these changes won’t really affect its interface.

To enforce the ability of an object to hide its data, the compiler limits the scope of instance variables—that is, limits their visibility within the program. But to provide flexibility, it also lets you explicitly set the scope at three different levels. Each level is marked by a compiler directive:

Directive

Meaning

@private

The instance variable is accessible only within the class that declares it.

@protected

The instance variable is accessible within the class that declares it and within classes that inherit it.

@public

The instance variable is accessible everywhere.

@package

On 64-bit, an @package instance variable acts like @public inside the image that implements the class, but @private outside.

This is analogous to private_extern for variables and functions. Any code outside the class implementation’s image that tries to use the instance variable will get a link error. This is most useful for instance variables in framework classes, where @private may be too restrictive but @protected or @public too permissive.

This is illustrated in Figure 2-1.


 

Figure 2-1  The scope of instance variables

Figure 2-1 The scope of instance variables


 

A directive applies to all the instance variables listed after it, up to the next directive or the end of the list. In the following example, the age and evaluation instance variables are private, name, job, and wage are protected, and boss is public.

@interface Worker : NSObject
{
    char *name;
@private
    int age;
    char *evaluation;
@protected
    id job;
    float wage;
@public
    id boss;
}

By default, all unmarked instance variables (like name above) are @protected.

All instance variables that a class declares, no matter how they’re marked, are within the scope of the class definition. For example, a class that declares a job instance variable, such as the Worker class shown above, can refer to it in a method definition:

- promoteTo:newPosition
{
    id old = job;
    job = newPosition;
    return old;
}

Obviously, if a class couldn’t access its own instance variables, the instance variables would be of no use whatsoever.

Normally, a class also has access to the instance variables it inherits. The ability to refer to an instance variable is usually inherited along with the variable. It makes sense for classes to have their entire data structures within their scope, especially if you think of a class definition as merely an elaboration of the classes it inherits from. The promoteTo: method illustrated earlier could just as well have been defined in any class that inherits the job instance variable from the Worker class.

However, there are reasons why you might want to restrict inheriting classes from directly accessing an instance variable:

  • Once a subclass accesses an inherited instance variable, the class that declares the variable is tied to that part of its implementation. In later versions, it can’t eliminate the variable or alter the role it plays without inadvertently breaking the subclass.

  • Moreover, if a subclass accesses an inherited instance variable and alters its value, it may inadvertently introduce bugs in the class that declares the variable, especially if the variable is involved in class-internal dependencies.

To limit an instance variable’s scope to just the class that declares it, you must mark it @private. Instance variables marked @private are only available to subclasses by calling public accessor methods, if they exist.

At the other extreme, marking a variable @public makes it generally available, even outside of class definitions that inherit or declare the variable. Normally, to get information stored in an instance variable, other objects must send a message requesting it. However, a public instance variable can be accessed anywhere as if it were a field in a C structure. For example:

Worker *ceo = [[Worker alloc] init];
ceo->boss = nil;

Note that the object must be statically typed.

Marking instance variables @public defeats the ability of an object to hide its data. It runs counter to a fundamental principle of object-oriented programming—the encapsulation of data within objects where it’s protected from view and inadvertent error. Public instance variables should therefore be avoided except in extraordinary cases.

fuente: http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/index.html

Temas relacionados:

Opiniones de este contenido

Esta web se reserva el derecho de suprimir, por cualquier razón y sin previo aviso, cualquier contenido generado en los espacios de participación en caso de que los mensajes incluyan insultos, mensajes racistas, sexistas... Tampoco se permitirán los ataques personales ni los comentarios que insistan en boicotear la labor informativa de la web, ni todos aquellos mensajes no relacionados con la noticia que se esté comentando. De no respetarse estas mínimas normas de participación este medio se verá obligado a prescindir de este foro, lamentándolo sinceramente por todos cuantos intervienen y hacen en todo momento un uso absolutamente cívico y respetuoso de la libertad de expresión.




 No hay opiniones. Sé el primero en escribir.


Tu opinión

Contenidos Indexados
El Arte del Bonsái Ficus - Variedades

 3
  
 217538

English Adverbios de Frecuencia

 10
  
 201236

Informática Generador de códigos de barras en PHP

 13
  
 163346

Quejas denuncias estafas Descubre quién te visita en Facebook?

 16
  
 138572

English Something - Anything

 2
  
 129981

Marketing digital Cómo ganar dinero con un periódico o revista digital

 2
  
 126318

Informática Mejores herramientas para Eventos Virtuales

 1
  
 98052

OTROS MISCELANEA El permiso por puntos Español

 0
  
 86613

Actualidad Las profesiones que van a desaparecer.

 0
  
 84697

Autores

Admin

Este autor tiene 31 artículos publicados.

PARENTESYS

Este autor tiene 13 artículos publicados.

MILES

Este autor tiene 3 artículos publicados.


Newsletter

Suscríbete a nuestros boletines