instantiating objects in c sharp

To make an actual instance, or object, of the Dog class, you must declare the object and allocate memory for the object. These two steps combined are necessary to create, or instantiate, the object. Here's how you do it.

First, you declare the object by writing the name of the class (Dog) followed by an identifier (name) for the object or instance of that class:

Dog milo;  // declare milo to be an instance of Dog

This is not unlike the way you create a local variable; you declare the type (in this case Dog) followed by the identifier (milo). Notice also that (as with variables) by convention the identifier for the object uses Camel Notation. Camel Notation is just like Pascal Notation except that the very first letter is lowercase. Thus, a variable or object name might be myDog, designatedDriver, or plantManager.

The declaration alone doesn't actually create an instance, however. To create an instance of a class you must also allocate memory for the object using the keyword new.

milo = new Dog();  // allocate memory for milo

You can combine the declaration of the Dog type with the memory allocation into a single line:

Dog milo = new Dog();

This code declares milo to be an object of type Dog and also creates a new instance of Dog. You'll see what the parentheses are for later in this chapter in the discussion of the constructor.

In C#, everything happens within a class. No methods can run outside of a class, not even Main(). The Main() method is the entry point for your program; it is called by the operating system, and it is where execution of your program begins. Typically, you'll create a small class to house Main(), because like every method, Main() must live within a class. Some of the examples in this book use of a class named Tester to house Main():

Even though Tester was created to house the Main() method, you've not yet instantiated any objects of type Tester.

Classes versus objects:

One way to understand the difference between a class and an instance (object) is to consider the distinction between the type int and a variable of type int.

Similarly, you can't assign values to fields in a class; you must assign values to fields in an object.

Memory Allocation: The Stack Versus the Heap

Objects created within methods are called local variables. They are local to the method, as opposed to belonging to the object, as member variables do. The object is created within the method, used within the method, and then destroyed when the method ends. Local objects are not part of the object's state — they are temporary value holders, useful only within the particular method.

Local variables of intrinsic types such as int are created on a portion of memory known as the stack. The stack is allocated and de-allocated as methods are invoked. When you start a method, all the local variables are created on the stack. When the method ends, local variables are destroyed.

These variables are referred to as local because they exist (and are visible) only during the lifetime of the method. They are said to have local scope. When the method ends, the variable goes out of scope and is destroyed.

C# divides the world of types into value types and reference types. Value types are created on the stack. All the intrinsic types (int, long, etc.) are value types, and thus are created on the stack.

Classes, on the other hand, are reference types. Reference types are created on an undifferentiated block of memory known as the heap. When you declare an instance of a reference type, what you are actually declaring is a reference, which is a variable that refers to another object. The reference acts like an alias for the object.

That is, when you write:

Dog milo = new Dog();

the new operator creates a Dog object on the heap and returns a reference to it. That reference is assigned to milo. Thus, milo is a reference object that refers to a Dog object on the heap. It is common to say that milo is a reference to a dog, or even that milo is a Dog object, but technically that is incorrect. milo is actually a reference object that refers to an (unnamed) Dog object on the heap.

The reference milo acts as an alias for that unnamed object. For all practical purposes, however, you can treat milo as if it were the Dog object itself.

The implication of using references is that you can have more than one reference to the same object.

Your next step is to create a simple Dog class with only one member variable (field) called weight. Note that this field is given a keyword, public, which specifies that any method of any class can access this field. public is what is known as an access modifier.

you create a second reference to Dog and initialize it by setting it equal to milo. This creates a new reference to the same object on the heap.
Dog fido = milo;

Notice that this is syntactically similar to creating a second int variable and initializing it with an existing int, as you did before:

int secondInt = firstInt; Dog fido = milo;

The difference is that Dog is a reference type, so fido is not a copy of milo — it is a second reference to the same object to which milo refers.

When you change the weight of that object through the fido reference:

fido.weight = 7;

you change the weight of the same object to which milo refers. The output reflects this:

Milo: 7, fido: 7

It isn't that fido is changing milo, it is that by changing the (unnamed) object on the heap to which fido refers, you simultaneously change the value of milo because they refer to the same unnamed object.

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.

Public methods are part of the class's public interface: they define how this class behaves. Private methods are "helper methods" used by the public methods to accomplish the work of the class. Because the internal workings of the class are private, helper methods need not (and should not) be exposed to other classes.

No comments:

Post a Comment