Chapter 6: Introducing Classes and Objects


This chapter introduces the class. The class is the foundation of C# because it defines the nature of an object. Furthermore, the class forms the basis for object-oriented programming. Within a class are defined both code and data. Because classes and objects are fundamental to C#, they constitute a large topic, which spans several chapters. This chapter begins the discussion by covering their main features.

Class Fundamentals

Since all C# program activity occurs within a class, we have been using classes since the start of this book. Of course, only extremely simple classes have been used, and we have not taken advantage of the majority of their features. Classes are substantially more powerful than the limited ones presented so far.

Let’s begin by reviewing the basics. A class is a template that defines the form of an object. It specifies both the data and the code that will operate on that data. C# uses a class specification to construct objects. Objects are instances of a class. Thus, a class is essentially a set of plans that specify how to build an object. It is important to be clear on one issue: A class is a logical abstraction. It is not until an object of that class has been created that a physical representation of that class exists in memory.

The General Form of a Class

When you define a class, you declare the data that it contains and the code that operates on it. While very simple classes might contain only code or only data, most real-world classes contain both.

In general terms, data is contained in data members defined by the class, and code is contained in function members. It is important to state at the outset that C# defines several specific flavors of data and function members. For example, data members (also called fields) include instance variables and static variables. Function members include methods, constructors, destructors, indexers, events, operators, and properties. For now, we will limit our discussion of the class to its essential elements: instance variables and methods. Later in this chapter, constructors and destructors are discussed. The other types of members are described in later chapters.

A class is created by use of the keyword class. Here is the general form of a simple class definition that contains only instance variables and methods:

 class classname{    // declare instance variables    access type var1;    access type var2;    // ...    access type varN;    // declare methods    access ret-type method1(parameters) {        // body of method    }    access ret-type method2(parameters) {        // body of method    }        // ...    access ret-type methodN(parameters) {        // body of method    } }

Notice that each variable and method declaration is preceded with access. Here, access is an access specifier, such as public, which specifies how the member can be accessed. As mentioned in Chapter 2, class members can be private to a class or more accessible. The access specifier determines what type of access is allowed. The access specifier is optional and if absent, then the member is private to the class. Members with private access can be used only by other members of their class. For the examples in this chapter, all members will be specified as public, which means that they can be used by all other code—even code defined outside the class. We will return to the topic of access specifiers in Chapter 8.

Note 

In addition to an access specifier, the declaration of a class member can also contain one or more type modifiers. These modifiers are discussed later in this book.

Although there is no syntactic rule that enforces it, a well-designed class should define one and only one logical entity. For example, a class that stores names and telephone numbers will not normally also store information about the stock market, average rainfall, sunspot cycles, or other unrelated information. The point here is that a well-designed class groups logically connected information. Putting unrelated information into the same class will quickly destructure your code.

Up to this point, the classes that we have been using have only had one method: Main( ). However, notice that the general form of a class does not specify a Main( ) method. A Main( ) method is required only if that class is the starting point for your program.

Defining a Class

To illustrate classes, we will be evolving a class that encapsulates information about buildings, such as houses, stores, offices, and so on. This class is called Building, and it will store three items of information about a building: the number of floors, the total area, and the number of occupants.

The first version of Building is shown here. It defines three instance variables: floors, area, and occupants. Notice that Building does not contain any methods. Thus, it is currently a data-only class. (Subsequent sections will add methods to it.)

 class Building {   public int floors;    // number of floors   public int area;      // total square footage of building   public int occupants; // number of occupants }

The instance variables defined by Building illustrate the way that instance variables are declared in general. The general form for declaring an instance variable is shown here:

 access type var-name;

Here, access specifies the access, type specifies the type of variable, and var-name is the variable’s name. Thus, aside from the access specifier, you declare an instance variable in the same way that you declare local variables. For Building, the variables are preceded by the public access modifier. As explained, this allows them to be accessed by code outside of Building.

A class definition creates a new data type. In this case, the new data type is called Building. You will use this name to declare objects of type Building. Remember that a class declaration is only a type description; it does not create an actual object. Thus, the preceding code does not cause any objects of type Building to come into existence.

To actually create a Building object, you will use a statement like the following:

 Building house = new Building(); // create an object of type building

After this statement executes, house will be an instance of Building. Thus, it will have “physical” reality. For the moment, don’t worry about the details of this statement.

Each time you create an instance of a class, you are creating an object that contains its own copy of each instance variable defined by the class. Thus, every Building object will contain its own copies of the instance variables floors, area, and occupants. To access these variables, you will use the dot (.) operator. The dot operator links the name of an object with the name of a member. The general form of the dot operator is shown here:

 object.member 

Thus, the object is specified on the left, and the member is put on the right. For example, to assign the floors variable of house the value 2, use the following statement:

 house.floors = 2;

In general, you can use the dot operator to access both instance variables and methods.

Here is a complete program that uses the Building class:

 // A program that uses the Building class. using System; class Building {   public int floors;    // number of floors   public int area;      // total square footage of building   public int occupants; // number of occupants } // This class declares an object of type Building. class BuildingDemo {   public static void Main() {     Building house = new Building(); // create a Building object     int areaPP; // area per person     // assign values to fields in house     house.occupants = 4;     house.area = 2500;     house.floors = 2;     // compute the area per person     areaPP = house.area / house.occupants;     Console.WriteLine("house has:\n  " +                       house.floors + " floors\n  " +                       house.occupants + " occupants\n  " +                       house.area + " total area\n  " +                       areaPP + " area per person");   } }

This program consists of two classes: Building and BuildingDemo. Inside BuildingDemo, the Main( ) method creates an instance of Building called house. Then the code within Main( ) accesses the instance variables associated with house, assigning them values and using those values. It is important to understand that Building and BuildingDemo are two separate classes. The only relationship they have to each other is that one class creates an instance of the other. Although they are separate classes, code inside BuildingDemo can access the members of Building because they are declared public. If they had not been given the public access specifier, their access would have been limited to the Building class, and BuildingDemo would not have been able to use them.

Assume that you call the preceding file UseBuilding.cs. Compiling this program creates a file called UseBuilding.exe. Both the Building and BuildingDemo classes are automatically part of the executable file. The program displays the following output:

 house has:   2 floors   4 occupants   2500 total area   625 area per person

Actually, it is not necessary for the Building and the BuildingDemo class to be in the same source file. You could put each class in its own file, called Building.cs and BuildingDemo.cs, for example. Just tell the C# compiler to compile both files and link them together. For example, you could use this command line to compile the program if you split it into two pieces as just described:

 csc Building.cs BuildingDemo.cs

If you are using the Visual Studio IDE, you will need to add both files to your project and then build.

Before moving on, let’s review a fundamental principle: each object has its own copies of the instance variables defined by its class. Thus, the contents of the variables in one object can differ from the contents of the variables in another. There is no connection between the two objects except for the fact that they are both objects of the same type. For example, if you have two Building objects, each has its own copy of floors, area, and occupants, and the contents of these can differ between the two objects. The following program demonstrates this fact:

 // This program creates two Building objects. using System; class Building {   public int floors;    // number of floors   public int area;      // total square footage of building   public int occupants; // number of occupants } // This class declares two objects of type Building. class BuildingDemo {   public static void Main() {     Building house = new Building();     Building office = new Building();     int areaPP; // area per person     // assign values to fields in house     house.occupants = 4;     house.area = 2500;     house.floors = 2;     // assign values to fields in office     office.occupants = 25;     office.area = 4200;     office.floors = 3;     // compute the area per person in house     areaPP = house.area / house.occupants;     Console.WriteLine("house has:\n  " +                       house.floors + " floors\n  " +                       house.occupants + " occupants\n  " +                       house.area + " total area\n  " +                                  areaPP + " area per person");     Console.WriteLine();     // compute the area per person in office     areaPP = office.area / office.occupants;     Console.WriteLine("office has:\n  " +                       office.floors + " floors\n  " +                       office.occupants + " occupants\n  " +                       office.area + " total area\n  " +                       areaPP + " area per person");   } }

The output produced by this program is shown here:

 house has:   2 floors   4 occupants   2500 total area   625 area per person office has:   3 floors   25 occupants   4200 total area   168 area per person

As you can see, house’s data is completely separate from the data contained in office. Figure 6-1 depicts this situation.

image from book
Figure 6-1: One object’s instance variables are separate from another’s.




C# 2.0(c) The Complete Reference
C# 2.0: The Complete Reference (Complete Reference Series)
ISBN: 0072262095
EAN: 2147483647
Year: 2006
Pages: 300

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net