I have explained a few times already that when we are dealing with objects, most of the times we are not working with the original class itself – the blueprint, but we are actually create copies of it called instances. The process of creating an instance (copy) of a class (blueprint) is called instantiation. In this light, we can say that an object is the instance itself.
Like I explained in a few occasions already, we can imagine this process of classes and their instantiation by making a similarity with the real world. In the previous lessons, we have used our Oven class to demonstrate the purpose of creating an Oven object. In real life, this would be the blueprint, the prototype of the oven. In practice, we are not going to make a new blueprint or prototype each time we are going to sell an oven. Instead, we will use that blueprint to create many copies of it, which can be sold. The copies can be customized, for example, a set of ovens can have their color white, while others can be gray. The original unique blueprint doesn’t specify a color for the oven, it only specifies that the oven can have a color.
Similarly, when we create a class, we are actually creating a blueprint. When we will want to use that class, it is very rarely that we will actually use the class itself. Instead, we will create copies of it called instances. These instances can be customized, and they are independent one of another.
In official programming manuals, you will encounter two terms: the state of an object and its behavior. While the state of the object is specific for each object itself (for example, our Oven‘s object color, or model, which can be individualized for each item), the behavior is common for all instances of that class (all Oven objects have a TurnOn() or TurnOff() method).
But, enough talking. Lets actually see how we are instantiating a class, though we have done this a few times already.
1 |
Oven myOven; |
So, the way we are instantiating a class is by using the name of the class to be instantiated, followed by the name we want to give to our new object (copy). If you look carefully, this is no different than doing this:
1 |
int myInt; |
Starts to looks familiar? We learned by now that the way we are declaring a variable is by specifying its type, followed by its name. So, we can see that instantiation is nothing else but the creation of a variable, of a custom type. Instead of creating a primitive type (types defined by default in C#), we are actually creating a new type. In conclusion, we are declaring a new variable of type Oven.
So far, so good. But we have learned that in order to use a variable we have declared, we first need to initialize it with a value. We cannot do this:
1 2 |
int myInt; Console.WriteLine(myInt); |
just like we cannot do this:
1 2 |
Oven myOven; Console.WriteLine(myOven.Height); |
because the compiler will complain about Use of of unassigned variable.
We know that we can initialize a variable this way:
1 2 |
int myInt = 4; Console.WriteLine(myInt); |
But, in the case of our Oven variable, we can’t specify a default value, because there is no default value specified for our custom type. Instead, we need to make a call to the constructor of the class, of which we talked in the previous lesson.
1 |
Oven myOven = new Oven(); |
The only new thing in the above code is the usage of the new operator. What you don’t know is the fact that every type has a constructor, even the primitive ones. This example works perfectly:
1 |
int myInt = new int(); |
in which case, myInt is initialized to the default value of the int type. This is equivalent to
1 |
int myInt = 0; |
The above speculations don’t have much value, they are only used to prove and dissect a concept in detail. In short, in order to create and use a variable, we need to declare and initialize it. This is also true for objects, with a few differences:
- objects declaration and initialization is also called instantiation.
- objects can only be initialized by calling their constructor.
- calling the constructor of an object always requires the new operator before the call.
- all primitive types (int, float, bool, etc) except string are value types. Objects are always reference types.
Since we created our first class example using a separated file for it, I need to specify that in order to declare and use our class object, we need a different place to do that, not do it inside that class itself. Instead, we are declaring and initializing it inside the Main() method of our program. This is how our class file should look like:
and this is where we instantiate it:
Of course, if we declared a constructor with parameters, we specify them in the instantiation call:
1 |
Oven myOven = new Oven("EKK6450AOX", "white", 40, 85, 60, 60); |
After we instantiated it, we can start accessing the properties and methods of our object. You will notice them in Intellisense, as soon as you start typing:
And we can assign values or perform actions on it:
1 2 3 4 |
Oven myOven = new Oven(); myOven.Color = "white"; myOven.Weight = 40; myOven.Start(); |
Final note, when creating an object with the operator new, two things happen: memory is set aside for this object and its data members are initialized. This means that:
1 2 3 |
Oven myOven = new Oven(); Console.WriteLine(myOven.Weight); myOven.Start(); |
will not give us a compiler error, even if we did not specifically initialized our Weight property with any value. Instead, the console will display the default value for the type of the the Weight property, in this case, 0, because 0 is the default value of type int.
Tags: class, instantiation, new operator, object oriented programming, objects, OOP, operators