Go Back

In Ctrl: C# Classes, Encapsulation and Methods

Sep 14th 2020

Classes serve two main purposes, each of which is a way to encapsulate, or separate code in a manageable way. First of all, a class in C# connects data within it with code that manipulates it. Secondly, a class determines access to its contents. Encapsulation is essentially restricting or granting access to members of a class, which is one of the main concepts of Object-Oriented Programming. To put it simply, a class is a description of something to be created from it, a blueprint of sorts, and the whole process of structuring a project while thinking of blueprints for different things that you'll need is called OOD, Object-Oriented Design.

There are two main types of class members, those being public and private. A public class member can be accessed from anywhere outside the class, however, a private one would be locked inside the class which has been declared or initialized in, thus granting direct access to no piece of code that's outside the class. That said, we can still access private members from outside the class, albeit indirectly, using public methods that are within the class and do have access to private variables. That is very important, as that way we are hiding our private variables away, restricting direct access to them from outside the class, and effectively blocking any process from changing those variables in an unpredictable manner. To better grasp the idea of having a variable to be used only in a certain way, I'll be explaining the aforementioned methods, but quite before that, let's give types of class members a closer look.

In C#, there are 4 keywords that determine access to a class member, those being: public, private, protected, and internal. These keywords are called, much expectedly, access modifiers and if none of them are present in a declaration or initialization of some variable, the compiler will automatically perceive it as private. Let's look at a simple Triangle class:

Triangle.cs

class Triangle{
    public int side_one;
    public int side_two;
    public int side_three;

    int perimeter; // same as private int perimeter;
    private int area;
}

Let's say, this is all that's going for the Triangle class. We can see, it has 3 public variables (fields, if you will), and 2 private ones. Say, you wanted to reach those side variables directly from another file, you certainly could do that, but what about those 2 privates? If you are following this post and are trying to reach private variables from another C# file (which is, of course, within your project directory), you can see for yourself that your IDE won't even suggest them, simply because they are not visible from there. What can we do about that? Remember how I said, I'd also go over methods?

So, a method is essentially a function - a block of code that takes input, works on it according to some algorithm, and lastly sometimes gives back what's called an output. How is then a method any different from a function, you ask? Well, methods are used explicitly for working on class variables. Let's put it this way. A class defines, describes something that'll be made out of it. The product we create according to this description is called an object. So, an object, by default, knows some things about itself. A triangle object made out of Triangle class knows that it has 3 sides, a perimeter, and an area. A triangle can also do some things, like, for example, calculate its perimeter. That, if anything, would be a method. Since we can't just jump out of the class and say "This triangle's perimeter is 50", we need to create a public method that has access to private variables and will manipulate them in an expected way, or rather, the way we want it to. Let''s expand out Triangle class a bit:

Triangle.cs

class Triangle{
    public int side_one;
    public int side_two;
    public int side_three;
    public int height;

    int perimeter; // same as private int perimeter;
    private int area;

    public int Perimeter(){
        perimeter = side_one + side_two + side_three;
        return perimeter;
    }

    public int Area(){
        area = (height * side_one) / 2;
        return area;
    }
}

A couple of things were added. Let's go step by step. I added the height field since it's a needed value in an area formula. I added methods Perimeter() and Area() that work on perimeter and area private variables respectively. As you can see, a method's syntax consists of 6 parts, from left to right: access modifier > data type > identifier > parameters > curly braces > method body.

  1. The access modifier, as already mentioned, determines the type of access to the identifier.
  2. The data type keyword tells us, of what data type will the returned value be. If it's void, it means that the method returns nothing. Keep in mind that if the data type keyword is anything other than void, you must have your method return something, or you'll be met with an error telling you to do just that.
  3. The identifier is a name you give to your method, you call, reference your methods using the identifier.
  4. Those parentheses house method parameters, if it has any. A method parameter is a local variable that's only visible inside the body of that method.
  5. Curly braces encapsulate the body of the method.
  6. The method body is where all the logic of the method goes into.

See how, using public methods, we are able to reach private variables indirectly? You could say, we abstracted perimeter and area variables by making them private and reachable only by methods, blocks of code that work on those variables exactly how we want them to. So, one would not just barge in from another C# file and set the perimeter of our Triangle to 5, which would be ridiculous.

Now that we've scratched the surface of classes, we can talk about objects and spawn some while we're at it. Objects are custom data types and are outlined in classes. An int is a base data type that comes with almost all languages by default and represents a whole number. float is also a default one, representing decimal numbers and so on. When you declare and int, what you actually do is declaring an object of type int. What if we wanted to have a data type of Triangle? There's no such data type by default in any programming language, so we have to make it ourselves, and we apparently aleady have Triangle a class up and running. All that's left to create an object of type Triangle is to declare it and use our class as a blueprint:

Program.cs

Triangle sample_object = new Triangle();
// We have created an object of type Triangle.
// Now we can access the object's variables and methods via . (dot) operator.
sample_object.side_one = 6; // Reaching public variables directly
sample_object.side_two = 7;
sample_object.side_three = 5;

int perimeter = sample_object.perimeter(); // Reaching private variables 
// via public method and storing returned value in a new variable.