Back
#csharp

Back to Basics - Object Paradigm (1) My first steps and the object

Post published 11 months ago - Suggest Changes

My first steps and the object

This article is the first one of the Object Paradigm subplaylist of Back to Basics, it will present to you the basics of object oriented programming.

The object paradigm or object-oriented programming is a dominant paradigm in C#, as the functional paradigm is in F#.

What is it?

A class is the medium of encapsulation, it is an aggregate of data and functions grouped together to give representation and behavior to a single entity. However, it remains an abstraction of this idea of object.

To clarify this idea, we can start with a real life example: a door. It has several properties, such as its size, whether it has a lock, whether it is sliding, what color it is, etc.

We can thus deduce with this door an object in an abstract way, separating its properties and its behaviors. The purpose of object programming is to design services to serve the abstract purpose of a subject.

Concrete example

Surely you want an example with code? Well, we can materialize this example with our favorite language.

public class Door
{
    int _height;
    int _width;
    Color _color;
    
    bool _hasLatch;
    bool _isSliding;
}
Why are there underscores on properties? All programming languages except for exceptions are accompanied by rules, which are called conventions. We must respect them to allow others to read our code without having to worry and without wasting their time.

Coding conventions

Moreover, we prefer to have one class per file, so we have a Door.cs file that has only this Door class.

We can now create a door in our program:

Door door = new Door();

Super simple innit ?

We are talking here about instantiation of a class with the default constructor; super complicated right? But don't worry!

The lifetime of an object

public partial class MainForm : Form
{
    void Button1Click(object sender, EventArgs e)
    {
        Door door = new Door();
    }

    void Button2Click(object sender, EventArgs e)
    {
        door.Close();
    }
}

Button1Click and Button2Click define the behavior of the two buttons on my window when I click on one of them. When I click on Button1, it creates a door, when I click on Button2, the door closes.

Here we can approach the concept of scope, a scope is delimited by braces. How many scopes are there in this code ?

... Did you answer 2 ? Well you're wrong, there are actually three, and even more that we don't see explicitly here.

{
	door.Close();
}

We have the scope of the Button2Click() function

{
    Door door = new Door();
}

The scope of the Button1Click() function

{
    void Button1Click(object sender, EventArgs e)
    {
        Door door = new Door();
    }

    void Button2Click(object sender, EventArgs e)
    {
        door.Close();
    }
}

The scope of the MainForm class.

When we leave the scope of the Button1Click function, the variable will no longer exist, and therefore the Button2Click() function uses a variable that does not exist in its scope. This will result in an error.

  • In a scope, a variable defined in a class is a member variable and can be accessed anywhere in the class.

  • But there is another concept which is the memory reference: if a variable holds the reference of an object and then referees a new one, the reference of the first object is lost; but we will see this concept which is a little more complicated in another article!

This, this is my class

In a class, we can use a new keyword/variable, and without much surprise it is: this. It can be found everywhere in programming languages advocating the object paradigm. In Python, in Java, everywhere! But sometimes in a different way.

This variable refers to the object in use.

Let's improve a little bit our code snippet seen before:

public partial class MainForm : Form
{
    private Door _door = new Door();
    void Button1Click(object sender, EventArgs e)
    {
        Door door = new Door();
    }

    void Button2Click(object sender, EventArgs e)
    {
        door.Close();
    }
}

We now have a member variable, _door; we can use it anywhere in our class by referencing it with the keyword this. This reference is usually implicit:

public partial class MainForm : Form
{
    private Door _door = new Door();
    void Button1Click(object sender, EventArgs e)
    {
        Door door = new Door();
    }

    void Button2Click(object sender, EventArgs e)
    {
        this._door.Close();
    }
}

Although our this is well placed, it is not mandatory to specify it.

public partial class MainForm : Form
{
    private Door _door = new Door();
    void Button1Click(object sender, EventArgs e)
    {
        Door Door = new Door();
    }

    void Button2Click(object sender, EventArgs e)
    {
        _door.Fermer();
    }
}

But what is going on? What color is the Door? How are the properties of my class defined?

  • When no value is assigned to a property, C# gives them a value called default values.

We can find them in this documentation on GitHub : Default values

But I don't want C# to give them default values, I want to be able to define them myself!

Object constructors

As in real life, our door doesn't build itself, we need Bob the handyman to define all the properties that our pretty door will take!

A new thing to learn is the constructors; we define what happens when we instantiate the class.

But tell me Bob, what does a constructor look like?

A constructor is written in the class that we want to declare it within, let's go back to our Door class which is in the file: Door.cs.

public class Door
{
    int _height;
    int _width;
    Color _color;
    
    bool _hasLatch;
    bool _isSliding;

    Door(int height, int width, Color color)
    {
        _height = height;
        _width = width;
        _color = color;
    }
}
You can have as many builders as you want! But think about the relevance of having 500 of them.

We now have a constructor that takes 3 arguments as parameters, now when we want to create a Door we will need to specify its height, width and color.

public partial class MainForm : Form
{
    private Door _door = new Door(1, 2, Color.Aqua);
    void Button1Click(object sender, EventArgs e)
    {
        Door Door = new Door(); // It won't work, there's not any constructor that matches empty argument
    }

    void Button2Click(object sender, EventArgs e)
    {
        _door.Fermer();
    }
}

We then specify all this information in the constructor of our member variable. Our Door will be 1 in height, 2 in width, and painted in Aqua color.

Oops, my IDE has drawn a little red wave below Door, what's going on? If we just move the mouse over this little wave we see the following message: Cannot access private constructor 'Door(int, int, Color)' here`

What the hell is going on, Bob, what the hell did you do to me? Did you rip me off?

Access modifiers

An access modifier can be applied to classes, methods and attributes. They ensure the control of inheritance conditions, access to elements and data modification by other objects.

List of access modifier keywords

The Microsoft documentation offers a special table summarizing the visibility keywords, so you don't even need to make a small table!

MSDN summary table

You will then have an example and the different visibility specifiers rules available.

Now let's fix the problem

We want the constructor to be public so that anyone can use it.

public class Door
{
    private int _height;
    private int _width;
    private Color _color;
    
    bool _hasLatch;
    bool _isSliding;

    public Door(int height, int width, Color color)
    {
        _height = height;
        _width = width;
        _color = color;
    }
}

No more little red wave, phew...

But why can't I access the attributes of my Door with the keyword this?

By default in C#, all attributes in a class are implicitly private but it's always good to make it clear that they are private for those who did not know.

This concludes the first article on object-oriented programming.

Summary of this subplaylist:

  • My first steps and the object
  • Encapsulation
  • Inheritance
  • Polymorphism
  • Good practices
  • Object paradigm, the best paradigm ?