Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Microsoft CSharp Programming For The Absolute Beginner (2002) [eng]-1.pdf
Скачиваний:
46
Добавлен:
16.08.2013
Размер:
15.71 Mб
Скачать

Figure 5.3: With a good strategy, you can beat the computer much of the time, but not always.

The design of the snowball fight is simple. Both the player and the opponent are custom classes that have a lot in common. They have three properties: name, snowballs, and strength. Each player starts with three snowballs and, to win, has to make more during the fight. Each player also begins with three lives. When a player has been hit three times, that player loses the fight. The computer opponent is like the human player but has features that enable it to automatically play against the user.

Inheritance and Encapsulation

To make the snowball fight and other programs in the book, you must learn a few tricks about building classes. To illustrate these new concepts, I’ll build a few more critters like the ones in Chapter 4, “Objects and Encapsulation: The Critter Program.” The basic critter is interesting, but what if you want to make new kinds of critters that share the same behavior but exhibit different characteristics? For example, you might want to make a new kind of critter that is grumpy.

When programmers began using objects, they quickly realized the importance of being able to make changes to objects. Computer scientists (who love to obfuscate simple ideas by using techie terms) think that objects should support inheritance and polymorphism. These fancy words describe some simple but important ideas. Inheritance works much like genetics. Objects can have children and grandchildren, and an object’s descendants will inherit traits from the parents and grandparents. Polymorphism means that an object can have the same kind of behavior as its relatives but can implement that behavior differently. Don’t worry if these explanations leave you cold for now. I just want you to have a bird’s−eye view of these concepts before digging into specific examples later in this chapter.

Creating a Constructor

Imagine that you want to write a program using several critters. Each critter could have a different name and different characteristics (perhaps different starting values for hunger and happiness). Using the Critter class from Chapter 4, you could do it, but you’d have to create each critter in several steps. First, you’d have to create the critter, and then you’d need another statement of code to modify each characteristic. It would look something like this:

Critter myCritter = new Critter();

102

myCritter.name = "alpha"; myCritter.age = 10;

Although this is not difficult, a more convenient way to create a critter would enable you to initialize all its values at the same time. You could set up a critter with a line like this:

Critter myCritter = new Critter("alpha", 10, 9, 0);

The critter automatically assumes the name alpha, a happiness level of 10, a hunger level of 9, and an age of 0. (The age of 0 means that it will age after the first turn) You can apply a set of parameters whenever you create an instance of the critter class. Classes (such as the Critter) can have a special method called a constructor. A class’s constructor is a special method that is used to help create the critter. The constructor is automatically called whenever you create an instance of the class when using the new keyword.

Adding a Constructor to the Critter Class

I took the Critter class from Chapter 4 and added a constructor to it:

using System;

namespace CritterConstructor

{

///<summary>

///Critter with a constructor

///</summary>

public class Critter { // your basic critter

//instance variables private string pName; private int pFull = 10; private int pHappy = 10; private int pAge = 0;

//constructor

public Critter(string theName, int fullness, int happiness, int theAge){

name = theName; pFull = fullness; pHappy = happiness; pAge = theAge;

} // end constructor

public string name

public string talk() ...

public void age() ...

public void play() ...

public void eat() ...

}// end class

}// end namespace

I minimized all the properties and methods so that you can focus on the new part of the critter. Constructors are special methods that have the same name as the class. A constructor is usually public, and you do not have to specify a return value because the constructor will return an instance of the class as its value. Whenever you make an instance of a class (remember, the class is a

103

recipe, and instances are the cookies), the computer looks for a constructor. The constructor usually has special instructions for getting the class started. In this case, I added a constructor for the Critter class that accepts four parameters. Each parameter is mapped to a specific instance variable. Constructors are typically used to initialize instance variables, even in more complex classes. The other nice thing about a constructor is that you know that any code inside a constructor will happen as soon as the object is created. Therefore, any code you want to run at the beginning of the class’s life span should be written in the constructor. Constructors can have parameters just like any other method.

The Critter class does not have a Main() method. In any given namespace, it generally makes sense for only one class to have a Main() method. However, your project can (and usually will) have many classes and several instances of each class. The Critter class is not intended to be an executable program, so I will use it inside other classes that do have a Main() method. When you look at the files created by the .NET compiler, the programs that have a Main() method usually have an associated .exe (executable) file. Those that do not have a Main() method are compiled into dynamic linked libraries (.dll files). You might have heard that the only difference between an .exe file and a .dll file is that an executable (.exe) file has a Main() method and a dynamically linked library (dll) doesn’t. This is a generalization (and not completely true). Important internal differences exist between these files, but for the purposes of this book, this is a reasonable simplification.

Creating the CritViewer Class

If you type in the Critter class from the preceding section and attempt to run it, it will compile, but it won’t run. Often, you make classes that are meant to be used as parts inside other classes. A gas tank, for example, is an important part, or class, of the automobile. Gas tanks have parts and require assembly. When a gas tank is finished, it is sent to the auto assembly plant and installed. The gas tank is a class, but you can’t drive it because it’s designed to be part of a larger assembly. The program itself is one object (like the car), but it usually comprises constituent objects. Only the primary object needs a Main() method.

The Critter class will not stand on its own, so you need a container class to demonstrate the critter’s capabilities. In Chapter 4, you use a menu class to do this. Here, you use a much simpler program to contain the critter so that you can concentrate on new ways of building objects. The Critter Constructor program featured in Figure 5.4 demonstrates a version of the Critter program, with one class for a viewer and the modified Critter class with a constructor.

Figure 5.4: The critter viewer demonstrates the basic functionality of the critter.

Hint

104

Building a simple container to demonstrate and test a new class is a common strategy of object−oriented programmers. Because an object is encapsulated, it should work as well in one program as in another. You can create very straightforward programs to test your objects before you use the objects in a more complex program. With this technique, you are more likely to isolate errors in your custom classes before you add them to complex assemblies, where more can go wrong.

To demonstrate my new critter, I’ll build a CritterViewer class, which is reasonably simple:

using System;

namespace CritterConstructor

{

///<summary>

///CritViewer is a simple class designed simply to hold a critter

///Demonstrates self−instantiation

///Andy Harris, 12/21/01

///</summary>

class CritViewer

{

static void Main(string[] args)

{

// the main method simply creates an instance of the

/// critviewer object

CritViewer cv = new CritViewer(); } // end main

//This next method is the constructor for CritViewer public CritViewer(){

Critter myCritter = new Critter("alpha", 10, 10, 0); Console.WriteLine("I'm in critViewer"); Console.WriteLine(myCritter.talk());

Console.WriteLine();

Console.WriteLine("Please press Enter key to continue");

Console.ReadLine();

} // end constructor

} // end CritViewer Class

}// end namespace

Note the simplicity of the Main() method in this code:

static void Main(string[] args)

{

// the main method simply creates an instance of the

/// critviewer object

CritViewer cv = new CritViewer(); } // end main

Reviewing the Static Keyword

So far in this book, most of the code appears in the Main() method of the program. Although this approach is fine for these simple programs, it has limitations because the Main() method must be declared a static method. The keyword static in the preceding code means that the Main() method can be called before the class exists. A static method can be called without requiring an instance of the class. For example, most of the methods in the Convert class in Chapter 2, "Branching and Operators: The Math Game," are static methods. You don’t have to create an instance of the Convert class to use its methods. Likewise, the WriteLine() method of the Console class is static.

105

Соседние файлы в предмете Программирование на C++