Constructors and this
Problem
A €0 coffee
You create a product, just like in the last lesson, and fill in the fields line by line. You forgot one line:
Product coffee = new Product();coffee.Name = "Coffee";coffee.Quantity = 2;Console.WriteLine(coffee.Name + ": €" + coffee.Price * coffee.Quantity);Coffee: €0The coffee costs €0. The compiler does not complain: as far as it can tell, the price has a value, 0. The more fields a class has, the easier it is to miss one. And a product without a price should not be able to exist at all.
The idea
Constructor: no object without this data
A class can say what it needs before you can create an object from it. That is what the constructor is for: a special method that runs on new.
class Product{ public string Name; public double Price; public int Quantity;
public Product(string name, double price, int quantity) { Name = name; Price = price; Quantity = quantity; }}
class Program{ static void Main() { Product coffee = new Product("Coffee", 7.50, 2); Console.WriteLine(coffee.Name + ": €" + coffee.Price * coffee.Quantity); }}Coffee: €15- The constructor has exactly the same name as the class:
Product. - It has no return type, not even
void. - Its parameters are the data a product cannot do without. You pass them in the parentheses of
new:new Product("Coffee", 7.50, 2).
Now there is no way to forget the price. If you pass two arguments instead of three, the program does not compile.
public Product(string name, double price, int quantity){ Name = name; Price = price; Quantity = quantity;}
Product coffee = new Product("Coffee", 7.50, 2);Console.WriteLine(coffee.Name + ": €" + coffee.Price * coffee.Quantity);Step by step, in words
- new sets aside a new object. Its fields hold default values.
- The constructor runs. The arguments are copied into its parameters.
- Name = name: from the parameter into the field of the object.
- The same for the price and the quantity.
- The constructor is done and the parameters disappear. coffee gets an arrow to the finished object.
- The object comes out of new already filled in, so the price is not 0.
The idea
this: the field of this object
In C# the field is Name and the parameter is name. The names differ by the capital letter, so Name = name; is clear: the field is on the left, and the parameter is on the right.
You can write the same thing with this: the object being created right now. this.Name is "the Name field of this object":
public Product(string name, double price, int quantity){ this.Name = name; this.Price = price; this.Quantity = quantity;}Here this is optional. You will need it when the field and the parameter have the same name. You will see such fields (lowercase) in the "Encapsulation" lesson: there, this.balance = balance; is the only way to reach the field.
Try it
Find the bug
Pick the line with the bug.
Name = Name; stores the field in itself, and it stays null. You need Name = name;, with the parameter on the right. The compiler only gives a warning (CS1717: "Assignment made to same variable"), so watch the warnings.
The idea
What about new Product() from the last lesson?
In the last lesson there was no constructor, and new Product() worked. If you do not write a constructor, the compiler adds an empty one with no parameters. It is called the default constructor, and it leaves the fields with their default values.
As soon as you write your own constructor, the empty one is gone:
Product empty = new Product();error CS7036: There is no argument given that corresponds to the required parameter 'name' of 'Product.Product(string, double, int)'That is the point: a product without a name and price can no longer be created. If you still need an empty constructor, write it yourself.
The idea
Several constructors
Most products in the cart come one at a time. Typing 1 every time gets tedious.
You can give the class a second constructor, without the quantity. It sits next to the first one:
public Product(string name, double price){ Name = name; Price = price; Quantity = 1;}This is the overloading from the "Methods" module: one name, different parameters. On new, the compiler picks the constructor based on the arguments.
More precisely, if you are curious
The two constructors repeat the same lines. Instead, the shorter one can call the longer one:
public Product(string name, double price) : this(name, price, 1){}: this(...) after the parentheses calls another constructor of the same class before the body runs. Here the body is empty.
This way, if you add a price check tomorrow, you write it in only one constructor.
Try it
Which constructor?
What will the program print?
class Product{ public string Name; public double Price; public int Quantity;
public Product(string name, double price) { Name = name; Price = price; Quantity = 1; }
public Product(string name, double price, int quantity) { Name = name; Price = price; Quantity = quantity; }}
Product bread = new Product("Bread", 1.20);Product milk = new Product("Milk", 2.10, 3);Console.WriteLine(bread.Quantity + " " + milk.Quantity);new Product("Bread", 1.20) has two arguments, so the constructor with two parameters is called. It stores a quantity of 1. For the milk, three arguments are passed, so the other constructor is called.Try it
What is the constructor called?
What goes in the blank?
class Book
{
public string Title;
public string Author;
public (string title, string author)
{
Title = title;
Author = author;
}
}Book: the constructor has exactly the same name as the class, with the same capital letter.Exercise
Objects created whole
Solve these in your editor. Every class gets a constructor with parameters for all of its fields.
1. Person. A Person class with a name and an age. Create two people and print their details.
Maria, 34 yearsPeter, 19 years2. Animal. An Animal class with a species and an age. Create a 3-year-old cat and a 7-year-old dog.
Species: cat, age: 3Species: dog, age: 73. Dance move. A DanceMove class with a name and a duration in seconds. In the "Behavior" lesson, the move will learn to "perform" itself.
moonwalk: 5 sec.More practice
- A book with a constructor. Rewrite
Bookfrom the last lesson with aBook(title, author)constructor. How many lines did you save in Main? -
A product with two constructors.
Productwith two constructors, as in the lesson. Make an array{ new Product("Bread", 1.20, 2), new Product("Coffee", 7.50) }and print the name and quantity of each: "Bread x2", "Coffee x1". Then make the shorter constructor call the longer one. - Booking. A
Bookingclass with the guest's name, the number of nights, and the price per night. Print what the stay costs: for 3 nights at €85, that is €255.
Test