Learning to Code — Part 6: Classes & Objects

OK, so moving on…

…we now find ourselves within the Classes & Objects section. They haven’t really touched on anything related to classes yet, but we have seen them. While they’ve talked about using individual variables, of a data type, which can hold single values, classes are described as:

A data type that defines a set of variables and methods for a declared object.

I really like the way they explain what a class is in that you could have a class called BankAccount which has properties and methods for managing an individual bank account (i.e. balance, deposit, withdrawal, etc.). They also go on to say (and we’ve seen this before):

A class is like a blueprint. It defines the data and behavior of a type.

Starting off, they state that a class definition starts with the keyword class followed by a name for that class, like this:

class BankAccount {
// variables, methods, etc.
}

The last bit, within the first lesson of this section, is also really important as it doesn’t just leave that word, object, hanging there without explanation. While the class itself is not an object, it does define a data type for an object. An object, is a “thing” based on a class. When you create an object, it’s sometimes called an instance of a class.

They go on to talk more about objects relating them to how you can “declare” variables, stating that you can “declare” objects (or individual “instances” of a class). Then they relate it to what an “architect” does, and how they work with blueprints. Probably time to update that analogy.

Anyway, the architect prepares the design of all aspects of a new building using drawings (or as they call it, blueprints). Those drawings can, in turn, be used (in theory) over and over again, to create that same building. I do like, however, how they relate that to programming:

We define (or design) a class that is the blueprint for creating objects.

They do also refer to the term type, which is used to refer to a class name, as in, we’re creating an object of a particular type. So, once we’ve written the class, we can create objects based on it. The creation of an object is called instantiation. So, to round it up, an object is called an instance of a class.

Going further with objects, they discuss how an object has its own characteristics. Each objects has its own set of values (like a person has a name, age, gender, etc.) which differentiates them from another object of the same type (i.e. another person). These characteristics are known as properties. These properties describe the current state of an object.

Storing Data by Reference or Value

As has been seen before, there are two ways of storing data: by reference and by value. I have mentioned data types multiple times (such as int and double), and how they are used to declare variables that are value types. The value of those variables are stored in memory in a location called the stack. The description of the stack in the previous article, when trying to understand recursion, appears to be the same concept. So, when we see, for example, int x = 10; the value of the variable x is now stored in the stack.

Reference types are used for storing objects (versus values). For example, we talked about creating an instance/object of a class. That object is stored as a reference type. Whereas value types are stored in the stack, reference types are store in a part of the memory call the heap.

In trying to describe this further, the SoloLearn app explains that when an object is instantiated, the data for that object is stored on the heap. It’s memory address is stored in the stack. It then goes on to describe it this way:

That is why it is called a reference type — it contains a reference (the memory address) to the actual object on the heap. As you can see, the p1 object of the type Person on the stack stores the memory address of the heap where the actual object stored.
Stack is used for static memory allocation, which includes all your value types, like x.
Heap is used for dynamic memory allocation, which includes custom objects, that might need additional memory during the runtime of your program.

This seems important, and I’m not quite sure I understand. So, back to C-Sharp Corner and a post called C# Heap(ing) Vs Stack(ing) in .NET: Part I and the following, really understandable explanation:

The Stack is more or less responsible for keeping track of what’s executing in our code (or what is being “called”). The Heap is more or less responsible for keeping track of our objects (our data, well…most of it; we’ll get to that later).
Think of the Stack as a series of boxes stacked one on top of the next. We keep track of what’s going on in our application by stacking another box on top every time we call a method (called a Frame). We can only use what’s in the top box on the Stack. When we’re done with the top box (the method is done executing) we throw it away and proceed to use the stuff in the previous box on the top of the Stack.
The Heap is similar except that its purpose is to hold information (not keep track of execution most of the time) so anything in our Heap can be accessed at any time. With the Heap, there are no constraints as to what can be accessed like in the Stack. The Heap is like the heap of clean laundry on our bed that we have not taken the time to put away yet; we can grab what we need quickly.

I think, at this point, this is as far as the SoloLearn app would describe the stack and heap, so I’m going to take the previous definition as “enough information for now”.

Creating a Class

The next process it has us go through is to create an actual class. As I’ve been doing, I’m going to do this directly within Visual Studio, creating a new Console App called ClassExample. While it does already start out with a class called Program, I’m going create another class below it, with the following code:

class Person {
int age;
string name;
public void SayHi() {
Console.WriteLine(“Hi.”);
}
}

So, this class is called Person, it has two fields called age and name, and has a publicly available (meaning outside the class) method called SayHi.

Now that we have that class, we can instantiate an object (or create an instance) of that type within the Main method. This is done with an operator called new. So, to instantiate it, we use the following code within the Main method:

Person p1 = new Person();
p1.SayHi();

Translated into English, the first line means create a new Person object called p1. Now, the object called p1 has all of the functionality of the Person class. So, to call any public member of a class (such as the method called SayHi), you enter the name of the object, followed by a dot operator (.), and then the name of the method you want to call (as you can see in the second line of the code above. Just so you know, you can access more than just methods from within a class, but those members still need to be publicly available, as in the following:

class Dog {
public string name;
public int age;
}
static void Main(string[] args) {
Dog bob = new Dog();
bob.name = “Bobby”;
bob.age = 3;
Console.WriteLine(Bob.age);
}

Here’s what happens when this code is executed:

  • First, a new class is declared called Dog with two publicly available variables called name (which is a string) and age (which is an integer).
  • Next, within the Main method, a new instance of the class called Dog is instantiated, and is called bob.
  • Now that this new object, called bob, exists, it can access any of the publicly available members with the Dog class. First, it accesses the variable called name and sets it’s value to be Bobby. Then, it accesses the variable called age, and sets it’s value to be 3.
  • Finally, it writes the value of the variable age, within the object called Bob, which is an instantiation of the class called Dog, which is 3.

Encapsulation & Access Modifiers

Next, we come to another programmy word: encapsulation. It is the process of both, combining members together within a class, as well as potentially restricting access to those members to just the inner workings of the class. It’s implemented by using access modifiers, as we’ve seen before (such as public).

The public access modifier makes the member accessible from outside of the class. Conversely, the private access modifier is accessible only from inside the class. These two access modifiers are used within the following code:

class BankAccount {
private double balance=0;
public void Deposit(double n) {
balance += n;
}
     public void Withdaw(double n) {
balance -= n;
}
     public double GetBalance() {
return balance;
}
}

Within the code above, the balance member is only accessible within the class because it’s access modifier is set to private. So, as you can see, the three methods called Deposit, Withdraw and GetBalance (which are all public, and therefore accessible outside of the class) have access to the balance member. The balance member could not be accessed from outside of the BankAccount class. In reality, therefore, access to the balance member is known as restricted in that it can be read through the GetBalance method, and modified through the Deposit and Withdraw methods.

Constructors

Next up, is a concept that will get discussed a lot within the Revit API training: class constructors. It’s a:

Special member method of a class that is executed whenever a new object of that class is created. A constructor has exactly the same name as it’s class, is public, and does not have any return type.
class Person {
private int age;
public Person() {
Console.WriteLine(“Hi there”);
}
}

Within the code above, the lines in bold represent the constructor member method of the class called Person. Once the creation of an object of type Person is instantiated, the constructor is automatically called, like this:

static void Main(string[] args) {
Person p = new Person();
}

Initially, I didn’t understand why this was useful, and that last part about it being called automatically really didn’t jump out at me. The reason that this constructor is useful is that when the class is called, this special method is called automatically and immediately, so you don’t have to. So, imagine that when a new bank account is created, we wanted to have an email notification sent to the owner. While that could be done with separate public method, it wouldn’t happen automatically, as it would with a constructor.

It goes on to explain another benefit of constructors being that you can use them to set initial values for specific variables. I had to read through the following code a few times to understand exactly what it did, so, keep reading:

class Person {
private int age;
private string name;
public Person(string nm) {
name = nm;
}
     public string getName() {
return name;
}
}
static void Main(string[] args) {
Person p = new Person(“David”);
Console.WriteLine(p.getName());
}

Again, in the code above, the constructor is in bold. Here’s what happens:

  • First, a class called Person is created with two private (meaning, only accessible, directly, within the class) variables: an integer-based one called age, and a string-based one called name.
  • It also contains the public constructor method called Person, which declared a string-based variable called nm. Within it, the value that gets passed to this method when called, which was assigned to the variable nm, gets assigned to the string-based variable name. As a result of this, the private string-based variable, nm, can now be indirectly accessed.
  • Finally, it also contains a method called getName which returns the value of the string-based variable name.
  • Within the Main method, a new instance of the Person class is instantiated and is passed the value “David”. As a result of what was described in the second bullet point, the string-based variable nm now receives and is assigned the value “David” and, when the constructor method is executed, that value gets assigned to the string-based variable name (which, again, is now indirectly accessed).
  • Next, within the object called p (which is an instantiation of the class called Person), the getName method is called, and then returns the current value of the variable name (which is “David”), which then gets printed to the screen.

This is completely logical to me and, therefore, I understand it pretty well. Recalling the concept of overloading, as discussed in Part 5c, like any other method, this can be applied to constructor methods as well. As a reminder, overloading is when there are multiple methods with the same name and, based on the variable type being sent, the appropriate version of the method is called

Properties

I could stop this article here, and talk about the final section, Properties, within the next one, but, I’m moving right on, so the article will as well.

The SoloLearn app references the encapsulation of individual members of a class and the ability to provide access to them only through public methods. A property, however, is a member of a class that has a more flexible way of being read from, written to, or used to compute the value of a private field. These properties are used as if they were public, but they include special methods called accessors.

My eyes are already gazing down at the sample code which references get and set, which is something I’ve seen before, but never fully understood. Get and set are the previously mentioned “special accessors”.

They are Executable statements that help in getting (reading or computing) or setting (writing) a corresponding field.

It’s worth noting that the declaration of these accessors can include get or set, or both, as in the following code:

class Person {
private string name; this is the field
public string Name { this is the property
get { return name; }
set { name = value; }
}
}

As you can see within the code above, the privately accessible, string-based member called name is declared, and it is the field. The publicly available, string-based member called Name (notice the capital “N”) is a property because it has the aforementioned, special accessors called get and set. Within this code, the get method returns the current value of the, privately accessible, string-based member called name (notice the lowercase “n”), thus accessing it indirectly. Regarding the upper and lower case naming, typical coding convention is to have the name of the property be the same as the name of the private field, but with a capital letter.

Within the property, at first glance, I’d say the set accessor sets the value of the name member to whatever the current value of the variable value is. However, the app describes the value keyword as a special keyword, which represents the value we assign to a property using the set accessor. I can’t say I completely understand this concept.

Over on Dot Net Perls, there’s a post which also states:

With parameters in a property, we can use the special keyword “value”. This way we do not need to specify the type. The type is determined by the enclosing property type.

In other words, since the type of the property is string, whatever the value of the argument is, which is sent to the member (called Name), it will need to be a string as well. This appears to be another “efficiency”. The point is, we don’t need to specify the type a second time.

I was getting a bit confused by the order of these two accessors, as well as what each of them has written within the curly braces. It seems like they should be opposite, and have the other one’s coding, but I think it gets interpreted this way:

  • The Name property first has to “get” it’s value, and it does this by returning to it, the property called name itself.
  • Next, since it now contains the property called name, it assigns it whatever, string-based value it receives (presumably when an object of type Person is instantiated.

I’m not sure if this is accurate, and would appreciate some feedback. Due to this uncertainty, however, I decided to do some Googling…

On the site Complete C# Material, there is a post called C# Get Set Modifier. They explain the get and set accessors in a very simple and understandable way:

…the get method is used for retrieving the value from the private field, whereas the set method is used for storing the value in private variables.

This then leads to the following code:

class Access {
private string name;
public print() {
Console.WriteLine(“\nMy name is “ + name);
}
     public string Name {
get { return name; }
set { name = value; }
}
}
static void Main(string[] args) {
Access ac = new Access();
Console.Write(“Enter your name:\t”);
ac.Name = Console.ReadLine();
ac.print();
Console.ReadLine();
}

So here’s what’s happening:

  • A class is declared called Access. Within it, a private, string-based variable is created called name.
  • A method is declared within the Access class called print. Along with a received value for the variable called name, it will print to the screen, “My name is “ and then insert that value.
  • A constructor method is declared within the Access class called Name. It will automatically be called when an object of Access type is instantiated, and will first get a value that will be used for the string-based variable called name. Then, it will set that name variable equal to the value it received.
  • Within the Main method, first a new object of the Access type is instantiated, and is named ac, giving it access to all of the members of the Access class.
  • Next, it prints to the screen, “Enter your name:”.
  • After that, the user enters their name, and the constructor method called Name is executed. It gets the value that has been sent to it (i.e. the user’s name), and then sets it as the value for the variable name.
  • Next, the print method is called, which prints to the screen, “My name is: “ and then inserts the value that was assigned to the variable name.
  • Console.ReadLine(); simply keeps the window open on the screen.

I now have a pretty good understanding of how each method is called, as well as how values are retrieved, set as the value of variables, and then returned.

As mentioned before, you don’t have to include both get and set. By leaving out set for example, the property becomes read-only, as in the following:

class Person {
private string name;
public string Name {
get { return name; }
}
}

They also point out that a property can also be private, restricting it’s calling from within the class only. It also asks the appropriate question of, why use properties at all, versus just declaring the member variable as public, and then accessing it directly? Their answer is:

With properties you have the option to control the logic of accessing the variable.

In other words, you can have a certain condition evaluated in order to decide whether or not to assign the value being checked, to the variable itself. As in the following:

class Person {
private int age;
public int Age {
get { return age; }
set {
if (value > 0)
age = value;
}
}
}

When executed, the Age property will only assign the retrieved value to the variable age, if it is greater than 0.

When you do not need any custom logic, however, there is an efficiency that can be used. Instead of writing the following:

public string Name {
get { return name; }
set { name = value; }
}

You could simply write:

public string Name { get; set; }

That’s obviously shorter and quicker to write. The other thing that you don’t need to do is declare the private field name separately. The private field, which would be named name, is created by the property automatically. Therefore, the property is actually called an auto-implemented property or auto-property.

This brings us to the end of a rather lengthy post. I’m glad to have gone through it all in one shot, however, versus breaking it up into 3 or 4 parts. Any corrections or clarifications would be greatly appreciated.

Also, here’s a link to the previous article, Learning to Code — Part 5d: Making a Pyramid.