Classes and Objects : Part 1

( 4 users )

A Class is a fundamental concept of OOP (Object Oriented Programming). You can think of it as a template for a real world object. For example in a sentence - Alice is a human, human is a class of the real world object Alice. Classes provides a way to bind data and functions together in a box. It can be seen as a template of a real world object. In technical terms, you can call it is a user defined datatype..

Creating a class in C#

In C#, we use class to declare a class and we can create a class like this.


class ClassName
{
    <.. variables ..>
	<.. methods ..>
}
		

where statements can have variable statements and function statements. Let's see an example to understand better.


class House
{
	public int length;
	public int width;
	public int height;
}
		

In the above example, we created a class named - House. We have declared three variable length, width and height. An access modifier is prefixed in variable declaration. We have used public access modifier in this example. This means that we can access these variables outside the class as well. The access modifiers will be covered in detail later in this course.

Using a class in C#

Now that we have created a class, let's see how to use in our main application.

To use the class in our main program, we need to create an instance of the class. An instance of a class is also called an object of that class. Like we mentioned at the start of this chapter that a class is a template of an object. The object or instance is what we visualize as a real world object.

To create an instance of the class, we first declare a variable of that class type. Then we initialize it with a new keyword. This new keyword creates a new object of a class.

Run this code


using System;

class Program
{
	static void Main(string[] args)
	{
		Console.WriteLine("Using class");
		Console.WriteLine("");
			
		House house = new House();
		house.length = 50;
		house.width = 40;
		
		double area = house.length * house.width;
		Console.WriteLine("Area of the house = " + area);
		
		Console.Write("Press any key to continue...");
		Console.ReadKey(true);
	}
}

class House
{
	public int length;
	public int width;
}
		

In the above example, the phrase "new House()" creates an instance of class in memory and returns the reference of that instance. In this case, the reference will be assigned to the object "house". Now, all the public properties of that class can be accessed through that object which in this case are length and width.

Methods

A Method (also called function) in C# class is a block where we write statement of logics. For e.g. in previous chapters, we were using the Main() method to write statements. Let's modify the above class House :


class House
{
	public int length;
	public int width;
	
	public int Area() 
	{
		int area = length * width;
		return area;
	}
}
		

In the above example, we have created a method named "Area". To define a method, we have the following syntax:


return-type method-name(data-type variable1, data-type variable2)
{
	statement-1;
	statement-2;
	.
	.
	statement-N;
	
	return return-value;
}
		

In simple way we can say that a method takes some input variable(s), do some processing with those variable(s) and finally returns the result back. In the above example we created a method Area() which takes no input and return the product of length and width variables of class House.

To use this method we can simply create an instance of the class and call the method over that object. Let's see how.


using System;

class Program
{
	static void Main(string[] args)
	{
		Console.WriteLine("Using methods");
		Console.WriteLine("");
			
		House house = new House();
		house.length = 50;
		house.width = 40;
		
		double area = house.Area(); // house.length * house.width is replaced by Area()
		Console.WriteLine("Area of the house = " + area);
		
		Console.Write("Press any key to continue...");
		Console.ReadKey(true);
	}
}
	

In this above example, we have moved our calculation logic in side the Area method. Let's add one more method that takes parameters. We are going to add a Price(string locality) method that takes a single parameter locality which can be either urban or rural or anything else.


class House
{
	public int length;
	public int width;
	
	public int Area() 
	{
		int area = length * width;
		return area;
	}
	
	public double Price(string locality) 
	{
		double priceFactor = 0.0;
		if(locality == "urban")
		{
			priceFactor = 1.5;
		}
		else if(locality == "rural")
		{
			priceFactor = 0.5;
		}
		else
		{
			priceFactor = 1.0;
		}
		
		return priceFactor * Area() * 100;
	}
}
		

In the above example, based on locality we are calculating the price factor and finally we are calculating the over all price with this logic - priceFactor * Area() * 10000. If you notice, we have used Area() method inside the Price method. Let's use this in our main program.

Run this code


using System;

class Program
{
	static void Main(string[] args)
	{
		Console.WriteLine("Using methods");
		Console.WriteLine("");
			
		House house = new House();
		house.length = 50;
		house.width = 40;
		
		double area = house.Area();
		Console.WriteLine("Area of the house = " + area);
		double price = house.Price("urban");
		Console.WriteLine("Price of the house = " + price);
		
		Console.Write("Press any key to continue...");
		Console.ReadKey(true);
	}
}
	

Constructor

A constructor is used to initialize the variables of a class. In the above example we have initialized the house variable with "new House()". The "House()" here is a constructor. Even if we have not defined any constructor in our House class as of now, a default constructor gets associated with it. In this case it is "House()".

A constructor is defined with the same name as of class. We generally define constructor to initialize the class variables since a constructor is invoked as soon as the object of that class is created. For e.g. we could have initialized the length and width variables. Let's see.


class House
{
	public int length;
	public int width;
	
	//constructor
	public House()
	{
		length = 0;
		width = 0;
	}
	
	public int Area() 
	{
		int area = length * width;
		return area;
	}
}
		

In the above example, we have initialized the class variables under the constructor with some value. So, even if we do not assign values to length and width in our main program, calling the Area() method will not give an error.

We can also provides parameters to the constructor (aka Parameterized Constructor). Suppose we need to initialize the required data variables length and width at the time of object creation itself. This is required so that the in our main program, we could not modify these variables once the object is created. Let's modify previous example.


class House
{
	int length;
	int width;
	
	//constructor
	public House(int _length, int _width)
	{
		length = _length;
		width = _width;
	}
	
	public int Area() 
	{
		int area = length * width;
		return area;
	}
}
		

We have modified the constructor to take two parameters - _length and _width. Also, we have removed the public access modifier from the length and width variables declaration. Now in our main program, we can use like this:

Run this code


using System;

class Program
{
	static void Main(string[] args)
	{
		Console.WriteLine("Using constructor");
		Console.WriteLine("");
			
		House house = new House(50, 40);
		
		double area = house.Area(); // house.length * house.width is replaced by Area()
		Console.WriteLine("Area of the house = " + area);
		
		Console.Write("Press any key to continue...");
		Console.ReadKey(true);
	}
}
		

See how we passed arguments (50, 40) to the House constructor. Also, now length and width variables are not available to the house object because we have removed the "public" access modifier. In this way the length and width can not be changed once the object is initialized.

Garbage Collection

The Garbage Collection is an important concept in C# which defines the life cycle of an object (object creation to object destruction). C# is also a memory safe language which means we don't have to worry about the memory allocation and deallocation while declaring an object (unlike C, C++). The Garbage Collector is a part of .Net CLR and does the memory allocation and deallocation for us.

Note: Please note that we are not going to cover the entire Garbage Collection process as it is really a long topic in depth. However, we will cover some basic aspect of it.

When the garbage collector is initialized, it pulls some part of OS memory to form a managed heap. The managed heap is where all data corresponding to reference types variables is stored. The garbage collector allocates memory to an object in the managed heap and also deallocates from there.

This managed heap is organized into three categories called generations. These three generations are Generation 0, Generation 1 and Generation 2. The task of Garbage Collector is to find the unused object reference in each Generation.

Let's discuss the Garbage collection cycles with each generation.

Generation 0: Initially all objects are assigned to Generation 0 (unless it is a very large object which can directly go to the Generation 2 in some case). The Garbage Collector in Generation 0 runs frequently to find and deallocate unused references. The objects that remains after the Garbage Collection is executed in Generation 0 are promoted to Generation 1.

Generation 1: The garbage collector in Generation 1 runs less frequent to Generation 0. When it runs, again it checks for the unused object reference in the managed heap and deallocates the memory for them. The objects which are left are promoted to Generation 2.

Generation 2: The garbage collector in Generation 2 runs very much less frequent to Generation 1. Similar to previous generations, the unused references are deallocated. Since, there is no further generation in the managed heap after this, the valid references remains in this generation as it is.

The Garbage Collector executes automatically in different time intervals by the .Net CLR. However, we can explicitly call it using GC.Collect(int generation) method. This is not recommended and should be used in a very specific use case like memory extensive applications.

Destructor

Just as constructor used to initialize the variables of a class, the destructor is used to destroy the reference types variables of a class as soon as the object of the class gets destroyed or there are no more references being used in the rest of the program. This is a special method which is executed when the reference of its object is no more valid. Let's modify our house class to include a destructor.

NOTE : The most important point to note here is - The destructor method is executed when the Garbage Collector deallocated it's object reference from the memory.

In C#, we use ~<class-name> to declare a destructor and we can create a destructor like this.


~ClassName()
{
    statement-1;
	statement-2;
	.
	.
	statement-N;
}
		

Let's see this with an example.


class House
{
	int length;
	int width;
	
	//constructor
	public House(int _length, int _width)
	{
		length = _length;
		width = _width;
	}
	
	public int Area() 
	{
		int area = length * width;
		return area;
	}
	
	~House()
	{
		Console.WriteLine("This House's instance is being destroyed");
	}
}
		

Now let's modify our Main method.

Run this code


using System;

class Program
{
	static void Main(string[] args)
	{
		Console.WriteLine("Using destructor");
		Console.WriteLine("");
			
		House house = new House(50, 40);
		
		double area = house.Area(); 
		Console.WriteLine("Area of the house = " + area);
		
		Console.Write("Press any key to continue...");
		Console.ReadKey(true);
	}
}

/*

Output :

Using destructor

Area of the house = 2000
Press any key to continue...This House's instance is being destroyed

*/
		

As you can see the destructor's statement is executed as soon as the program ends.

To Do

* Note : These actions will be locked once done and hence can not be reverted.

1. Track your progress [Earn 200 points]

2. Provide your ratings to this chapter [Earn 100 points]

0
Note : At the end of this chapter, there is a ToDo section where you have to mark this chapter as completed to record your progress.