[ Team LiB ] Previous Section Next Section

4.1 Defining Classes

To define a new type or class, first declare it, and then define its methods and fields. Declare a class using the class keyword. The complete syntax is as follows:

[attributes] [access-modifiers] class identifier [:base-class]
{class-body}

Attributes are covered in Chapter 8; access modifiers are discussed in the next section. (Typically, your classes will use the keyword publicError! Bookmark not defined. as an access modifier.) The identifier is the name of the class that you provide. The optional base-class is discussed in Chapter 5. The member definitions that make up the class-body are enclosed by open and closed curly braces ({}).

C and C++ programmers take note: A C# class definition does not end with a semicolon, though if you add one, the program will still compile.

In C#, everything happens within a class. For instance, some of the examples in Chapter 3 make use of a class named Tester:

public class Tester
{

        public static int Main( )
        {
         /...
        }
}

So far, we've not instantiated any instances of that class; that is, we haven't created any Tester objects. What is the difference between a class and an instance of that class? To answer that question, start with the distinction between the type int and a variable of type int. Thus, while you would write:

int myInteger = 5;

you would not write:

int = 5;

You can't assign a value to a type; instead, you assign the value to an object of that type (in this case, a variable of type int).

When you declare a new class, you define the properties of all objects of that class, as well as their behaviors. For example, if you are creating a windowing environment, you might want to create screen widgets (more commonly known as controls in Windows programming) to simplify user interaction with your application. One control of interest might be a list box, which is very useful for presenting a list of choices to the user and enabling the user to select from the list.

List boxes have a variety of characteristics—for example, height, width, location, and text color. Programmers have also come to expect certain behaviors of list boxes: they can be opened, closed, sorted, and so on.

Object-oriented programming allows you to create a new type, ListBox, which encapsulates these characteristics and capabilities. Such a class might have member variables named height, width, location, and text_color, and member methods named sort( ), add( ), remove( ), etc.

You can't assign data to the ListBox type. Instead you must first create an object of that type, as in the following code snippet:

ListBox myListBox;

Once you create an instance of ListBox, you can assign data to its fields.

Now consider a class to keep track of and display the time of day. The internal state of the class must be able to represent the current year, month, date, hour, minute, and second. You probably would also like the class to display the time in a variety of formats. You might implement such a class by defining a single method and six variables, as shown in Example 4-1.

Example 4-1. Simple Time class
   using System;

   public class Time
   {
       // private variables
       int Year;
       int Month;
       int Date;
       int Hour;
       int Minute;
       int Second;

      // public methods
      public void DisplayCurrentTime( )
      {
         Console.WriteLine(
            "stub for DisplayCurrentTime");
      }


   }

   public class Tester
   {
      static void Main( )
      {
         Time t = new Time( );
         t.DisplayCurrentTime( );
      }

   }

The only method declared within the Time class definition is DisplayCurrentTime( ). The body of the method is defined within the class definition itself. Unlike other languages (such as C++), C# does not require that methods be declared before they are defined, nor does the language support placing its declarations into one file and code into another. (C# has no header files.) All C# methods are defined inline as shown in Example 4-1 with DisplayCurrentTime( ).

The DisplayCurrentTime( ) method is defined to return void; that is, it will not return a value to a method that invokes it. For now, the body of this method has been "stubbed out."

The Time class definition ends with the declaration of a number of member variables: Year, Month, Date, Hour, Minute, and Second.

After the closing brace, a second class, Tester, is defined. Tester contains our now familiar Main( ) method. In Main( ), an instance of Time is created and its address is assigned to object t. Because t is an instance of Time, Main( ) can make use of the DisplayCurrentTime( ) method available with objects of that type and call it to display the time:

t.DisplayCurrentTime( );

4.1.1 Access Modifiers

An access modifier determines which class methods—including methods of other classes—can see and use a member variable or method within a class. Table 4-1 summarizes the C# access modifiers.

Table 4-1. Access modifiers

Access Modifier

Restrictions

public

No restrictions. Members marked public are visible to any method of any class.

private

The members in class A that are marked private are accessible only to methods of class A.

protected

The members in class A that are marked protected are accessible to methods of class A and also to methods of classes derived from class A.

internal

The members in class A that are marked internal are accessible to methods of any class in A's assembly.

protected internal

The members in class A that are marked protected internal are accessible to methods of class A, to methods of classes derived from class A, and also to any class in A's assembly. This is effectively protected OR internal. (There is no concept of protected AND internal.)

It is generally desirable to designate the member variables of a class as private. This means that only member methods of that class can access their value. Because private is the default accessibility level, you do not need to make it explicit, but I recommend that you do so. Thus, in Example 4-1, the declarations of member variables should have been written as follows:

// private variables
private int Year;
private int Month;
private int Date;
private int Hour;
private int Minute;
private int Second;

Class Tester and method DisplayCurrentTime( ) are both declared public so that any other class can make use of them.

It is good programming practice to explicitly set the accessibility of all methods and members of your class. Although you can rely on the fact that class members are declared private by default, making their access explicit indicates a conscious decision and is self-documenting.

4.1.2 Method Arguments

Methods can take any number of parameters.[1] The parameter list follows the method name and is encased in parentheses, with each parameter preceded by its type. For example, the following declaration defines a method named MyMethod( ), which returns void (that is, which returns no value at all) and which takes two parameters: an integer and a button.

[1] The terms "argument" and "parameter" are often used interchangeably, though some programmers insist on differentiating between the argument declaration and the parameters passed in when the method is invoked.

void MyMethod (int firstParam, button secondParam)
{
  // ...
}

Within the body of the method, the parameters act as local variables, as if you had declared them in the body of the method and initialized them with the values passed in. Example 4-2 illustrates how you pass values into a method—in this case, values of type int and float.

Example 4-2. Passing values into SomeMethod( )
using System;

public class MyClass
{
   public void SomeMethod(int firstParam, float secondParam)
   {
      Console.WriteLine(
         "Here are the parameters received: {0}, {1}",
         firstParam, secondParam);
   }

}

public class Tester
{
   static void Main( )
   {
      int howManyPeople = 5;
      float pi = 3.14f;
      MyClass mc = new MyClass( );
      mc.SomeMethod(howManyPeople, pi);
   }

}

The method SomeMethod( ) takes an int and a float and displays them using Console.WriteLine( ). The parameters, which are named firstParam and secondParam, are treated as local variables within SomeMethod( ).

VB6 programmers take note: C# methods don't allow you to declare optional arguments. Instead, you have to use method overloading to create methods that declare different combinations of arguments. For more information, see Section 4.6, later in this chapter.

In the calling method (Main), two local variables (howManyPeople and pi) are created and initialized. These variables are passed as the parameters to SomeMethod( ). The compiler maps howManyPeople to firstParam and pi to secondParam, based on their relative positions in the parameter list.

    [ Team LiB ] Previous Section Next Section