7.6. Static and Instance MembersThe fields, properties, and methods of a class can be either instance members or static members . Instance members are associated with instances of a type, while static members are associated with the class and not with any particular instance. Methods are instance methods unless you explicitly mark them with the keyword static . The vast majority of methods will be instance methods. The semantics of an instance method are that you are taking an action on a specific object. From time to time, however, it is convenient to be able to invoke a method without having an instance of the class, and for that, you will use a static method. You access a static member through the name of the class in which it is declared. For example, suppose you have a class named Button and have instantiated objects of that class named btnUpdate and btnDelete . Suppose that the Button class has an instance method Draw( ) and a static method GetButtonCount( ) . The job of Draw( ) is to draw the current button, and the job of GetButtonCount( ) is to return the number of buttons currently visible on the form. You access an instance method through an instance of the classthat is, through an object: btnUpdate.SomeMethod( ); You access a static method through the class name, not through an instance: Button.GetButtonCount( ); 7.6.1. Invoking Static MethodsStatic methods are said to operate on the class, rather than on an instance of the class. They do not have a this reference, as there is no instance to point to. Static methods cannot directly access nonstatic members. You will remember that Main( ) is marked static. For Main( ) to call a nonstatic method of any class, including its own class, it must instantiate an object. For the next example, use Visual Studio 2005 to create a new console application named StaticTester . VS.NET creates a namespace StaticTester and a class named Class1 . Rename Class1 to Tester . Get rid of all the comments and the attribute [STATThread] that Visual Studio .NET puts above Main( ) . Delete the args parameter to Main( ) . When you are done, your source code should look like this: using System; namespace StaticTester { class Tester { static void Main( ) { } } } That is a good starting point. Until now, you've always done all the work of the program right in the Main( ) method, but now you'll create an instance method, Run( ) . The work of the program will now be done in the Run( ) method, rather than in the Main( ) method. Within the class, but not within the Main( ) method, declare a new instance method named Run( ) . When you declare a method, you write the accessor ( public ), followed by the return type, the identifier, and then parentheses: public void Run( ) The parentheses will hold parameters, but Run( ) won't have any parameters, so you can just leave the parentheses empty. Create braces for the method, and within the braces, just print "Hello World" to the console: public void Run( ) { Console.WriteLine("Hello world"); } Run( ) is an instance method. Main( ) is a static method and cannot invoke Run( ) directly. You will therefore create an instance of the Tester class and call Run( ) on that instance: Tester t = new Tester( ); When you type the keyword new , IntelliSense tries to help you with the class name. You'll find that Tester is in the list; it is a legitimate class like any other. On the next line, invoke Run( ) on your Tester object t . When you type t followed by the dot operator, IntelliSense presents all the public methods of the Tester class, as shown in Figure 7-1. Figure 7-1. IntelliSense
When your program is complete, it looks like Example 7-5. Example 7-5. Instance methods
The output looks like this: Hello world This is the model you'll use from now on in most console applications. The Main( ) method will be limited to instantiating an object and then invoking the Run( ) method. 7.6.2. Using Static FieldsA common use of static member variables , or fields, is to keep track of the number of instances/objects that currently exist for your class. In the next example, you create a Cat class. The Cat class might be used in a pet-store simulation. For this example, the Cat class has been stripped to its absolute essentials. The complete listing is shown in Example 7-6. An analysis follows the example. Example 7-6. Static fields
Here is the output: 0 cats adopted Frisky is 5 pounds 1 cats adopted Whisky is 7 pounds 2 cats adopted The Cat class begins by defining a static member variable, instances , that is initialized to zero. This static member field will keep track of the number of Cat objects created. Each time the constructor runs (creating a new object), the instances field is incremented. The Cat class also defines two instance fields: name and weight . These track the name and weight of each individual Cat object. The Cat class defines two methods: HowManyCats( ) and TellWeight( ) . HowManyCats( ) is static. The number of Cats is not an attribute of any given Cat ; it is an attribute of the entire class. TellWeight( ) is an instance method. The name and weight of each cat is per instance (each Cat has his own name and weight). The Main( ) method accesses the static HowManyCats( ) method directly, through the class: Cat.HowManyCats( ); Main( ) then creates an instance of Cat and accesses the instance method, TellWeight( ) , tHRough the instance of Cat : Cat frisky = new Cat( ) frisky.TellWeight( ); Each time a new Cat is created, HowManyCats( ) reports the increase. |