Learning to Code — Part 8b: More on Classes

Scott Rosenbloom
Aug 2, 2018 · 17 min read

THIS

Next up, the SoloLearn app goes through the this keyword, which refers to the current instance of the class, or, the current object. One important thing that they point out is using it to distinguish class members from other data like local variables of a method.

class Person {
private string name;
public Person(string name) {
this.name = name;
}
}
Person p1 = new Person(“John”);
  • Within the Person class, a private variable (meaning it’s only accessible within the class), which is of the data type string, is created, and is called name.
  • public Person(string name) { this.name = name; } is the constructor. Where it says this.name, it’s like saying, the current instatiation of the class Person, which is called p1. Since, when the Person class was sent the value “John”, and the constructor takes it and assigns it to the string-based variable called name, this.name = name; is the equivalent of saying, p1.name = name (and in the name property of p1 is equal to John).
ShowPersonInfo(this);
class Net {
public string Name { get; set; }
public Net (Perl perl) {
this.Name = perl.Name;
}
}
class Perl {
public string Name { get; set; }
public Perl(string name) {
this.Name = name;
Net net = new Net (this);
Console.WriteLine(net.Name);
}
}
class Program {
static void Main() {
Perl perl = new Perl(“Sam”):
}
  • Within the Perl class, first a publicly accessible, string-based variable called Name is created, gets the value Sam that was sent to the class when the object (called perl) was instantiated, and sets it as the value (of the variable Name).
  • Next, the publicly accessible constructor method called Perl is executed and, at the same time, declares a string-based variable called name.
  • The next line, this.Name = name; is the equivalent of perl.Name = name, or perl.Name = Sam. In other words, the current value of the property Name (of this instance of the Perl object, called perl) is now Sam.
  • After that, a new instance of the Net class is instantiated, and is called net. Also during that process, when the Net class is called, it is sent this, which are whatever the current values of the properties (and there’s only 1, called name, which is Sam).
  • Within the Net class, first a publicly accessible string-based variable called Name is created, gets the value Sam that was sent to the class when the object (called net) was instantiated, and sets it as the value (of the variable Name).
  • Next, the publicly accessible constructor method called Net is executed and, at the same time, declares a variable called perl of type Perl.
  • The next line, this.Name = perl.Name; is the equivalent of net.Name = perl.Name; The property called Name of the instance called perl was sent earlier. It’s value is Sam. So, net.Name = Sam. In other words, the current value of the property Name (of the instance of the Net object, called net) is now Sam.
  • Returning to the class Perl, the next line says to print to the screen, the current value of the Name property of the instance net (which is an instance of the class called Perl) which is Sam. In other words, Sam is printed to the screen.

readonly

The second half of this section talks about the readonly modifier. According to the app

class Person {
private readonly string name = “John”;
public Person(string name) {
this.name = name;
}
}
readonly string name;
const double PI;
const double PI = 3.14;
readonly double a = Math.Sin(60);
const double b = Math.Sin(60);

INDEXERS

OK, 2 topics left. First indexers, which allow objects to be indexed like an array. The SoloLearn app relates this back to what they mentioned about a string variable actually being an object of the String class, and that it’s actually an array of char (or character) objects. This is actually how the string class implements an indexer so we can access any character (or Char object) by it’s index.

string str = “Hello World”;
char x = str[4];
Console.WriteLine(x);
  • Then, he creates another class called Department, with 2 properties called DeptId and DeptName, whose values are also assigned using get and set. He also creates an array in the Department class called EmpList of the data type Employee (which is that first class he created). He does that because there is a “relationship” between the Department and the Employee.
  • Still within the Department class, he creates a constructor with some hardcoded values for DeptId and DeptName, and then, the previously initialized array called EmpList (of the data type Employee) gets declared, with 3 spots for new “Employees”, within which there are values of Id, EmpName and Salary (which were established within the Employee class).
  • Then, he creates 2 methods to be able to get an employee by either their id or their name, based on what a user enters when searching through the department.
namespace Indexer {
class Employee {
public int Id { get; set; }
public string EmpName { get; set; }
public double Salary { get; set; }
}
class Department {
public int DeptId { get; set; }
public string DeptName { get; set; }
Employee[] EmpList;

public Department() {
DeptId = 10;
DeptName = “Sales”;
EmpList = new Employee[3] {
new Employee { Id = 101, EmpName = “Alex”, Salary = 50000},
new Employee { Id = 102, EmpName = “Brad”, Salary = 45000 },
new Employee { Id = 103, EmpName = “Chris”, Salary = 40000 }
};
}
public Employee this[int id] {
get {
foreach (Employee emp in EmpList) {
if (id == emp.Id)
return emp;
}
return null;
}
}
public Employee this[string name] {
get {
foreach (Employee emp in EmpList) {
if (name == emp.EmpName)
return emp;
}
return null;
}
}
}
class Program {
static void Main(string[] args) {
Department dept = new Department();
Console.WriteLine(dept[101].EmpName);
Console.WriteLine(dept[“Brad”].Id);
Console.ReadLine();
}
}
}
  • Within the Department class, an integer-based property called DeptId is declared which can get a value from the user’s input, and then will set it as the current value of DeptId.
  • Next, a string-based property called DeptName is declared, which can get a value from the user’s input, and will then set it as the current value of DeptName.
  • After that, an array is declared of type Employee, called EmpList.
  • Still within the Department class, we see the Department method where “hardcoded” values are first assigned to the properties. First, DeptId is assigned the value of 10, and DeptName is assigned the value Sales.
  • Next, a new array object called EmpList is declared, of type Employee (calling the Employee class), and it is configured to have 3 elements within it.
  • On the next three lines, 3 new objects of the Employee class are instantiated and, when this is done, values for the properties within each are assigned. When the first Employee class is instantiated, the properties within them get these values, and set each to be the values of the indicated properties (i.e. Id, EmpName and Salary). The 3 bullet points above essentially create the “database” of employees.
  • Back to printing the results of dept[101].EmpName, we look at the first indexer called Employee, as it is the only place within the Department class that deals directly with the instantiated object (which we can tell by the use of the keyword this), and also receives an integer-based argument. This indexer, called Employee, looks at this instance of the object, and takes from the calling of it, the value within the brackets, and assigns it to the integer-based variable called id.
  • Next, it will then get the results of a foreach loop. The first time through, for the first Employee element within the array called EmpList, assign it’s properties to the variable called emp.
  • It will then test whether the current value of id, which was sent to it by the user as “101”, is equal to, within the current emp object (or, the first one within the array), the value of Id. In other words, does 101 equal, from within the first element in the EmpList array, the value assigned for Id, which is 101? Or, does 101 equal 101?
  • Since it does, it will return the current value of emp, which is the first element within the EmpList array, back to where it was initially called. In other words, you can swap out dept[101] for the current value of emp, which is the first element within the EmpList array.
  • The .EmpName looks to take the value assigned to EmpName from that array element. In other words, what is the value of EmpName within the array element that was sent back? The value is Alex. Therefore, Alex is printed to the screen.
  • Next, it will then get the results of a foreach loop. The first time through, for the first Employee element within the array called EmpList, assign it’s properties to the variable called emp.
  • It will then test whether the current value of name, which was sent to it by the user as “Brad”, is equal to, within the current emp object (or, the first one within the array), the value of EmpName. In other words, does Brad equal, from within the first element in the EmpList array, the value assigned for EmpName, which is Alex? Or, does Brad equal Alex?
  • Since is does not, the foreach loop moves onto the next item. It tests whether the current value of name, which was sent to it by the user as “Brad”, is equal to, within the current emp object (or, the second one within the array), the value of EmpName. In other words, does Brad equal, from within the second element in the EmpList array, the value assigned for EmpName, which is Brad? Or, does Brad equal Brad?
  • Since it does, it will return the current value of emp, which is the second element within the EmpList array, back to where it was initially called. In other words, you can swap out dept[“Brad”] for the current value of emp, which is the second element within the EmpList array.
  • The .Id looks to take the value assigned to Id from that array element. In other words, what is the value of Id within the array element that was sent back? The value is 102. Therefore, 102 is printed to the screen.
class Clients {
private string[] name = new string[10];
public string this[int index] {
get {
return names[index];
}
set {
names[index] = value
}
}
}
Clients c = new Clients();
c[0] = “Dave”;
c[1] = “Bob”;
Console.WriteLine(c[1]);
  • Within the Clients class, first, a new array object called string is instantiated of the built-in class called string, and configured with 10 elements.
  • An indexer called string is declared and assigns whatever value is set to it, as the value of the integer-based variable called index.
  • First, 0 is set as the value of index and, looking back to where it was called from, as Dave is the value for c[0], it returns it as the value of names[index], to be used in the future.
  • Then, it sets the current value of names[index], which is Dave, as the value of the first spot of the array.
  • Next, 1 is set as the value of index and, looking back to where it was called from, as Bob is the value for c[1], it returns it as the value of names[index], to be used in the future.
  • Then, it sets the current value of names[index], which is Bob, as the value of the second spot of the array.
  • As there are no more values being sent to the array, we move to the next line of code, which prints the value of the element in index position 2 of the array object c, which is Bob, to the screen.

OPERATOR OVERLOADING

And finally, operator overloading refers to the ability to redefine operators with custom actions. The example code they give refers to the result of adding two boxes, each with its own height and width, together to get a single, larger box. Overall, they’re adding the widths of each, and the heights of each, to get a new width and height, for a third box.

class Box {
public int Height { get; set; }
public int Width { get; set; }
public Box(int h, int w) {
Height = h;
Width = w;
}
public static Box operator+(Box a, Box b) {
int h = a.Height + b.Height;
int w = a.Width + b.Width;
Box res = new Box(h, w);
return res;
}
}
static void Main(string[] args) {
Box b1 = new Box(14, 3);
Box b2 = new Box(5,7);
Box b3 = b1 + b2;
Console.WriteLine(b3.Height);
Console.WriteLine(b3.Width);
}
  • Within the Box class, a publicly available constructor method is automatically executed taking the first value it receives, 14, and assigns it to a new, integer-based variable called h, and the second value it receives, 3, and assigns it to a new, integer-based variable called w.
  • Then, the integer-based property Height is called, from the beginning of the Box class, and it gets the value from where it was called, which was h, which is equal to 14, and then sets it (the Height property) equal to 14.
  • Next, the integer-based property Width is called, from the beginning of the Box class, and it gets the value from where it was called, which was w, which is equal to 3, and then sets it (the Width property) equal to 3.
  • Back to the Main class, another new object of the Box class is instatiated called b2.
  • Within the Box class, a publicly available constructor method is automatically executed taking the first value it receives, 5, and assigns it to a new, integer-based variable called w.
  • Then, the integer-based property Height is called, from the beginning of the Box class, and it gets the value from where it was called, which was h, which is equal to 5, and then sets it (the Height property) equal to 5.
  • Next, the integer-based property Width is called, from the beginning of the Box class, and it gets the value from where it was called, which was w, which is equal to 7, and then sets it (the Width property) equal to 7.
  • Back to the Main class, another new object of the Box class is instantiated called b3.
  • This time, however, it’s value is set to be the result of b1 + b2. Within the Box class is a method that defines the overloading operator +, which requires it to receive two objects of type Box, and it will name the first one a and the second one b.
  • Next, a new integer-based variable is declared called h, which is equal to the value of the Height property of the Box object called a, plus the value of the Height property of the Box object called b. In other words, h is equal to 14 + 5, or h = 19.
  • After that, a new integer-based variable is declared called w, which is equal to the value of the Width property of the Box object called a, plus the value of the Width property of the Box object called b. In other words, w is equal to 3 + 7, or h = 10.
  • A new object of the Box class is instantiated called res, and is sent the current values for h and w, which are 19 and 10 respectively.
  • Within the Box class, a publicly available constructor method is automatically executed taking the first value it receives, 19, and assigns it to a new, integer-based variable called h, and the second value it receives, 10, and assigns it to a new, integer-based variable called w.
  • Then, the integer-based property Height is called, from the beginning of the Box class, and it gets the value from where it was called, which was h, which is equal to 19, and then sets it (the Height property) equal to 19.
  • Next, the integer-based property Width is called, from the beginning of the Box class, and it gets the value from where it was called, which was w, which is equal to 10, and then sets it (the Width property) equal to 10.
  • Returning to where it was called, the next line of code returns the current Box object and it’s associated properties back to where it was called.
  • Back within the Main method, the next line prints to the screen, the value of the Height property of the Box object called b3, which is 19.
  • After that, the next line prints to the screen, the value of the Width property of the Box object called b3, which is 10.