Objects and References
Objects and References
Classes and Functions
Introduction
We have already learned how to create an object by declaring a variable of a class type. Here is an example:
using static System.Console;
Square sqr = new(248.57);
WriteLine("Square Characteristics");
WriteLine("----------------------------");
WriteLine("Side: {0}", sqr.Side);
WriteLine("Perimeter: {0}", sqr.CalculatePerimeter());
WriteLine("Area: {0}", sqr.CalculateArea());
WriteLine("============================");
public class Square(double side)
{
public double Side
{
get { return side; }
}
public double CalculatePerimeter()
{
return side * 4;
}
public double CalculateArea()
{
return side * side;
}
}
This would produce:
Square Characteristics ---------------------------- Side: 248.57 Perimeter: 994.28 Area: 61787.04489999999 ============================ Press any key to close this window . . .
As mentioned in our introduction to classes, when you declare a variable using the new operator, you are said to get a reference to the memory area where the object will be located.
Practical Learning: Introducing Parameters
namespace PayrollPreparation4.Models { internal class Employee { internal required int EmployeeNumber { get; set; } internal required string FirstName { get; set; } internal required string LastName { get; set; } internal required double HourlySalary { get; set; } } }
namespace PayrollPreparation40.Models { internal class TimeSheet { private int tsNbr; private int empl; private double salary; private double result; private double mon, tue, wed, thu, fri; internal TimeSheet(int ts, int emplNbr, double m, double t, double w, double h, double f) { tsNbr = ts; empl = emplNbr; mon = m; tue = t; wed = w; thu = h; fri = f; } internal int GetTimeSheetNumber() { return tsNbr; } internal int GetEmployeeNumber() { return empl; } internal double GetMondayWork() { return mon; } internal double GetTuesdayWork() { return tue; } internal double GetWednesdayWork() { return wed; } internal double GetThursdayWork() { return thu; } internal double GetFridayWork() { return fri; } private double GetSalary() { salary = 0.00; if (empl == 370_595) { salary = 28.25; } else if (empl == 826_384) { salary = 24.37; } else if (empl == 175_004) { salary = 26.97; } else if (empl == 697_415) { salary = 31.57; } else salary = 0.00; return salary; } internal double CalculateTimeWorked() { return mon + tue + wed + thu + fri; } internal double CalculateRegularTime(double time) { result = time; if (time is > 40.00) { result = 40.00; } return result; } internal double CalculateRegularPay(double time) { result = GetSalary() * time; if (time is > 40.00) { result = GetSalary() * 40.00; } return result; } internal double CalculateOvertime(double time) { result = 0.00; if (time is > 40.00) { result = time - 40.00; } return result; } internal double CalculateOvertimePay(double time) { result = 0.00; if (time is > 40.00) { result = salary * 1.50 * time; } return result; } internal double CalculateGrossPay(double time) { return CalculateRegularPay(time) + CalculateOvertimePay(time); } } }
Producing an Object
You can create a function that returns an object. To start, when creating the function, specify its return type as the desired class. In the body of the function, you can do anything you want. Before the closing curly bracket of the function, you must return an object of the class indicated as the returned type.
Practical Learning: Producing Objects
using PayrollPreparation4.Models; using static System.Console; PreparePayroll(); Employee Hire(int number) { Employee empl1 = new Employee() { EmployeeNumber = 370_595, FirstName = "Michael", LastName = "Carlock", HourlySalary = 28.25 }; Employee empl2 = new Employee() { EmployeeNumber = 826_384, FirstName = "Catherine", LastName = "Busbey", HourlySalary = 24.37 }; Employee empl3 = new Employee() { EmployeeNumber = 175_004, FirstName = "Andrew", LastName = "Sanders", HourlySalary = 26.97 }; Employee empl4 = new Employee() { EmployeeNumber = 697_415, FirstName = "Jennifer", LastName = "Simms", HourlySalary = 31.57 }; if (number == 370_595) { return empl1; } else if (number == 826_384) { return empl2; } else if (number == 175_004) { return empl3; } else if (number == 697_415) { return empl4; } return new Employee() { EmployeeNumber = 0, FirstName = "John", LastName = "Doe", HourlySalary = 0.00 }; } TimeSheet GetTimeWorked(int number) { TimeSheet ts1 = new TimeSheet(100_000, 370_595, 7, 8, 6.5, 8.5, 6.5); TimeSheet ts2 = new TimeSheet(205_000, 826_384, 9.5, 8, 10.5, 9, 8.5); TimeSheet ts3 = new TimeSheet(505_500, 175_004, 9, 10.5, 7, 9.5, 8.5); TimeSheet ts4 = new TimeSheet(202_240, 697_415, 8, 8, 8, 8, 8 ); if (number == 205_000) { return ts2; } else if (number == 202_240) { return ts4; } else if (number == 505_500) { return ts3; } else if (number == 100_000) { return ts1; } return new TimeSheet(0, 0, 0, 0, 0, 0, 0); } void PreparePayroll() { int nbr = 100_000; TimeSheet timeSheet = GetTimeWorked(nbr); Employee staff = Hire(timeSheet.GetEmployeeNumber()); double timeWorked = timeSheet.CalculateTimeWorked(); WriteLine("+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+"); WriteLine("FUN DEPARTMENT STORE"); WriteLine("======================================================="); WriteLine("Payroll Evaluation"); WriteLine("======================================================="); WriteLine("Employee Information"); WriteLine("-------------------------------------------------------"); WriteLine("Employee #: {0}", timeSheet.GetEmployeeNumber()); WriteLine($"Full Name: {staff.FirstName} {staff.LastName}"); WriteLine($"Hourly Salary: {staff.HourlySalary:f}"); WriteLine("======================================================="); WriteLine("Time Worked Summary"); WriteLine("--------+---------+-----------+----------+-------------"); WriteLine(" Monday | Tuesday | Wednesday | Thursday | Friday"); WriteLine("--------+---------+-----------+----------+-------------"); Write($" {timeSheet.GetMondayWork():f} | "); Write($"{timeSheet.GetTuesdayWork():f} | "); Write($"{timeSheet.GetWednesdayWork():f} | "); Write($"{timeSheet.GetThursdayWork():f} | "); WriteLine($"{timeSheet.GetFridayWork():f}"); WriteLine("========+=========+===========+==========+============="); WriteLine(" Pay Summary"); WriteLine("-------------------------------------------------------"); WriteLine(" Time Pay"); WriteLine("-------------------------------------------------------"); WriteLine(" Regular: {0:f} {1:f}", timeSheet.CalculateRegularTime(timeWorked), timeSheet.CalculateRegularPay(timeWorked)); WriteLine("-------------------------------------------------------"); WriteLine(" Overtime: {0:f} {1:f}", timeSheet.CalculateOvertime(timeWorked), timeSheet.CalculateOvertimePay(timeWorked)); WriteLine("======================================================="); WriteLine(" Net Pay: {0:f}", timeSheet.CalculateGrossPay(timeWorked)); WriteLine("======================================================="); }
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ FUN DEPARTMENT STORE ======================================================= Payroll Evaluation ======================================================= Employee Information ------------------------------------------------------- Employee #: 370595 Full Name: Michael Carlock Hourly Salary: 28.25 ======================================================= Time Worked Summary --------+---------+-----------+----------+------------- Monday | Tuesday | Wednesday | Thursday | Friday --------+---------+-----------+----------+------------- 7.00 | 8.00 | 6.50 | 8.50 | 6.50 ========+=========+===========+==========+============= Pay Summary ------------------------------------------------------- Time Pay ------------------------------------------------------- Regular: 36.50 1031.12 ------------------------------------------------------- Overtime: 0.00 0.00 ======================================================= Net Pay: 1031.12 ======================================================= Press any key to close this window . . .
A Class Type as a Parameter
An object of a class can be passed as argument. When creating a function, simply provide the name of a class as type followed by a name for the parameter. You can use a class from the .NET library or your own class. In the body of the function, you can ignore or use the parameter as you want. When it comes to a class passed as parameter, its public and internal members are available to the function that uses it. When calling the function, you must provide an object created from the class.
Passing an Object by Reference
You can create a function or method that uses a parameter of a class type and the argument can be passed by reference. To do this, when creating the function or method, in its parentheses, precede the class name of the parameter with the ref keyword. When calling the function or method, precede the argument with the ref keyword. As seen with primitive types, if you pass a parameter by reference, if the function or method modifies the argument, this causes it to produce an object with a new version.
Passing an Object Out
As mentioned already, another way to pass an argument by the out keyword. The concept also applies to objects passed as arguments.
Referencing an Object
A Referent
In our introduction to variables, we saw how to declare a variable using a primitive type. As a reminder, here is an example:
using static System.Console;
double side = 248.57;
WriteLine("Square Characteristics");
WriteLine("----------------------");
WriteLine("Side: {0}", side);
WriteLine("======================");
This would produce:
Square Characteristics ---------------------- Side: 248.57 ====================== Press any key to close this window . . .
When you declare a variable in a program, the compiler reserves some space for that variable in the computer memory. The location of a variable in memory is referred to as its address. As is the case for objects, when you declare a variable of a primitive type, a portion of the computer memory is allocated for it. On the other hand, if you declare a variable using the new operator, you are letting the compiler know that when it comes time to use that variable, you will use a reference to that variable or object, not the value itself. You can make the same suggestion to the compiler about a value of a primitive type. This means that you can declare a variable using a value type (int, double, etc), but let the compiler know that you will use a reference to that variable.
To use a reference to an existing variable, declare another variable of the same type as the original variable. The data type of the new variable declaration must be preceded by the ref keyword. Here is an example:
double side = 248.57;
ref double oneOf4Sides;
To indicate the variable to which you want to refer, you must assign its name to the new ref variable. You must precede the assigned variable with the ref keyword. This can be done as follows:
double side = 248.57;
ref double oneOf4Sides = ref side;
The original variable is called a referent.
After assigning the original variable (the referent) to the referenced variable, both the original variable and the referenced variable hold the same value. This is illustrated in the following code:
using static System.Console; double side = 248.57; ref double oneOf4Sides = ref side; WriteLine("Square Characteristics"); WriteLine("------------------------"); WriteLine("Original Side: {0}", side); WriteLine("Referenced Side: {0}", oneOf4Sides); WriteLine("========================");
This would produce:
Square Characteristics ------------------------ Original Side: 248.57 Referenced Side: 248.57 ======================== Press any key to close this window . . .
In the same way, you can declare as many referenced variables as you want and assign a previously declared referenced variable to each. All those referenced variables would hold the value of their referent. This can be illustrated as follows:
using static System.Console; double side = 248.57; ref double oneOf4Sides = ref side; ref double siding = ref side; ref double coast = ref side; WriteLine("Square Characteristics"); WriteLine("------------------------"); WriteLine("Original Side: {0}", side); WriteLine("Referenced Side: {0}", oneOf4Sides); WriteLine("Referenced Side: {0}", siding); WriteLine("Referenced Side: {0}", coast); WriteLine("========================");
This would produce:
Square Characteristics ------------------------ Original Side: 248.57 Referenced Side: 248.57 Referenced Side: 248.57 Referenced Side: 248.57 ======================== Press any key to close this window . . .
A Read-Only Referenced Variable
Remember that, to use a referenced variable, you must assign a previously declared and initialized variable to it. For the same reason, you cannot assign a constant value to a referenced variable. If you do, the compiler would throw an error. This makes a referenced variable is a read-only item. To re-enforce this idea, you can indicate to the compiler that your referenced variable a read-only item. To do this, follow the ref keyword of the referenced variable with the readonly keyword, as in ref readonly. This can be done as follows:
using static System.Console; double side = 248.57; ref readonly double oneOf4Sides = ref side; ref readonly double siding = ref side; ref readonly double coast = ref side; WriteLine("Square Characteristics"); WriteLine("------------------------"); WriteLine("Original Side: {0}", side); WriteLine("Referenced Side: {0}", oneOf4Sides); WriteLine("Referenced Side: {0}", siding); WriteLine("Referenced Side: {0}", coast); WriteLine("========================");
Updating a Referenced Variable
Remember that, when you have declared and initialized a referenced variable, it holds the same value as its referent. As a consequence, if you change the value of the original variable, the value of the referenced variable also changes. This can be illustrated as follows:
using static System.Console; double side = 248.57; ref readonly double oneOf4Sides = ref side; ref readonly double siding = ref side; side = 66.93; ref readonly double coast = ref side; ref readonly double quad = ref side; WriteLine("Square Characteristics"); WriteLine("------------------------"); WriteLine("Original Side: {0}", side); WriteLine("Referenced Side: {0}", oneOf4Sides); WriteLine("Referenced Side: {0}", siding); WriteLine("Referenced Side: {0}", coast); WriteLine("Referenced Side: {0}", quad); WriteLine("========================");
This would produce:
Square Characteristics ------------------------ Original Side: 66.93 Referenced Side: 66.93 Referenced Side: 66.93 Referenced Side: 66.93 Referenced Side: 66.93 ======================== Press any key to close this window . . .
In the same way, you can change the value of a referent as many times as possible and keep in mind that its associated referenced variable is updated. Therefore, if you are planning to use the value of a referenced variable, make sure it is holding the intended value at that time. As a result, you are free to change the value of the original variable any time but use the referenced variable, knowing that its value has automatically been updated. This can be verified in the following code:
using static System.Console; WriteLine("Square Characteristics"); WriteLine("------------------------"); double side = 248.57; ref readonly double oneOf4Sides = ref side; WriteLine("Original Side: {0}", side); WriteLine("Referenced Side: {0}", oneOf4Sides); WriteLine("------------------------"); side = 937.866; WriteLine("Original Side: {0}", side); WriteLine("Referenced Side: {0}", oneOf4Sides); WriteLine("------------------------"); side = 66.93; WriteLine("Original Side: {0}", side); WriteLine("Referenced Side: {0}", oneOf4Sides); WriteLine("------------------------"); side = 1057.48; WriteLine("Original Side: {0}", side); WriteLine("Referenced Side: {0}", oneOf4Sides); WriteLine("========================");
In the above example, notice that only the value of the referent is updated, but every time, the referenced variable is automatically updated. The above code would produce:
Square Characteristics ------------------------ Original Side: 248.57 Referenced Side: 248.57 ------------------------ Original Side: 937.866 Referenced Side: 937.866 ------------------------ Original Side: 66.93 Referenced Side: 66.93 ------------------------ Original Side: 1057.48 Referenced Side: 1057.48 ======================== Press any key to close this window . . .
Passing a Primitive Reference to an Object
Since a referenced variable holds a real value, you can use it wherever you would use the original variable. For example, you can pass it as argument. Here is an example where a referenced variable is passed to a constructor of an object:
using static System.Console; double side = 248.57; ref double oneOf4Sides = ref side; Square sqr = new Square(oneOf4Sides); WriteLine("Square Characteristics"); WriteLine("----------------------------"); WriteLine("Side: {0}", sqr.Side); WriteLine("Perimeter: {0}", sqr.CalculatePerimeter()); WriteLine("Area: {0}", sqr.CalculateArea()); WriteLine("============================"); public class Square(double side) { public double Side { get { return side; } } public double CalculatePerimeter() { return side * 4; } public double CalculateArea() { return side * side; } }
When it comes to using a referenced variable as argument, whenever you do that, you must let the compiler know so it would update its operation(s). This can be easily done by by re-calling the items that uses the argument. Here are examples:
using static System.Console; // Declare a variable double side = 248.57; // Create a referenced variable ref readonly double oneOf4Sides = ref side; // Pass the referenced variable to an object Square sqr = new(oneOf4Sides); WriteLine("Square Characteristics"); WriteLine("----------------------------"); WriteLine("Side: {0}", sqr.Side); WriteLine("Perimeter: {0}", sqr.CalculatePerimeter()); WriteLine("Area: {0}", sqr.CalculateArea()); WriteLine("============================"); // Change the value of the original variable side = 937.866; // Let the compiler know that the value passed to the object has changed sqr = new(oneOf4Sides); WriteLine("Square Characteristics"); WriteLine("----------------------------"); WriteLine("Side: {0}", sqr.Side); WriteLine("Perimeter: {0}", sqr.CalculatePerimeter()); WriteLine("Area: {0}", sqr.CalculateArea()); WriteLine("============================"); // Update the original variable side = 66.93; // Notify the compiler that the value of the object has changed sqr = new(oneOf4Sides); WriteLine("Square Characteristics"); WriteLine("----------------------------"); WriteLine("Side: {0}", sqr.Side); WriteLine("Perimeter: {0}", sqr.CalculatePerimeter()); WriteLine("Area: {0}", sqr.CalculateArea()); WriteLine("============================"); // Update the referent side = 1057.48; // Let the compiler know that there is a new value for the object sqr = new(oneOf4Sides); WriteLine("Square Characteristics"); WriteLine("----------------------------"); WriteLine("Side: {0}", sqr.Side); WriteLine("Perimeter: {0}", sqr.CalculatePerimeter()); WriteLine("Area: {0}", sqr.CalculateArea()); WriteLine("============================"); public class Square(double side) { public double Side { get { return side; } } public double CalculatePerimeter() { return side * 4; } public double CalculateArea() { return side * side; } }
This would produce:
Square Characteristics ---------------------------- Side: 248.57 Perimeter: 994.28 Area: 61787.04489999999 ============================ Square Characteristics ---------------------------- Side: 937.866 Perimeter: 3751.464 Area: 879592.633956 ============================ Square Characteristics ---------------------------- Side: 66.93 Perimeter: 267.72 Area: 4479.624900000001 ============================ Square Characteristics ---------------------------- Side: 1057.48 Perimeter: 4229.92 Area: 1118263.9504 ============================ Press any key to close this window . . .
Returning a Reference from a Method
In a class, you can create a method that returns a reference variable, or you can create methods that return reference variables.
Topics on Values and Objects
In some operations you perform, you may want to access a variable, an object, a function, etc. We already that there are various ways to do that. For some operations, you may want to get the name of a variable, an object, a function, etc. To help you get such a name, the C# language provides an operator named nameof. That operator is used like a function. That is, type it, followed by parentheses. In the parentheses, type the name of the variable, function, or object. You can also access a method of a class, a property of a class, etc. Here are examples:
using static System.Console; int number = 9383; void Announce() { WriteLine("Characteristics of Objects"); WriteLine("==========================="); } Announce(); House house = new House() { PropertyNumber = 938_448, Bedrooms = 5, Bathrooms = 3.5, MarketValue = 545_760 }; WriteLine("Number: {0}", number); house.Present(); WriteLine("==========================="); WriteLine("Name of Variable: {0}", nameof(number)); WriteLine("Name of Function: {0}", nameof(Announce)); WriteLine("Name of Object: {0}", nameof(house)); WriteLine("Name of Property: {0}", nameof(house.Bathrooms)); WriteLine("Name of Method: {0}", nameof(house.Present)); WriteLine("==========================="); internal class House { public int PropertyNumber { get; set; } public int Bedrooms { get; set; } public double Bathrooms { get; set; } public double MarketValue { get; set; } public void Present() { WriteLine("Property Listing"); WriteLine("---------------------------"); WriteLine("Property #: {0}", PropertyNumber); WriteLine("Bedrooms: {0}", Bedrooms); WriteLine("Bathrooms: {0}", Bathrooms); WriteLine("Market Value: {0}", MarketValue); } }
This would produce:
Characteristics of Objects =========================== Number: 9383 Property Listing --------------------------- Property #: 938448 Bedrooms: 5 Bathrooms: 3.5 Market Value: 545760 =========================== Name of Variable: number Name of Function: Announce Name of Object: house Name of Property: Bathrooms Name of Method: Present =========================== Press any key to close this window . . .
Practical Learning: Ending the Lesson
|
|||
Previous | Copyright © 2024, FunctionX | Sunday 21 January 2024 | Next |
|