So what exactly happens underwater when you create an object with new?
The statement new Clown()
is intended to create a new object from the class Clown
. The statement calls the so-called constructor
. A constructor looks like a method
, but is not a regular method.
How to recognize a constructor in C# code:
If you create a new class it will look like this:
public class Clown
{
}
Hey, but where is this constructor
then? Well, what actually happens underwater: when the compiler translates a class that has no constructor, it implicitly creates a supersimple one, this is called a default constructor
. The compiler pretends that it says this:
public class Clown
{
public Clown()
{
}
}
This seems a bit redundant, but we can give a constructor parameters: just like with methods.
public class Clown
{
// Fields <-- Fields we make private!
private string name;
private int height;
// constructors
public Clown(string name, int height)
{
this.name = name; // the word 'this' indicates
// that the Field 'name' is meant.
// the 'name' after the equals sign is the parameter.
this.height = height;
}
// methods
public string TalkAboutYourself()
{
return "My name is " + this.name
+ "and I'm " + this.height + " centimeters tall.";
}
}
The constructor parameters make it possible to immediately assign a name and height when creating an object of type Clown:
Clown aClown = new Clown("Popov", 170);
Clown otherClown = new Clown("Bassie", 186);
So we then have 2 objects of type Clown, shown here schematically:
In practice, programmers often work with class diagrams
, as an example below. Usually class diagrams have multiple classes.
A class is represented as a rectangle consisting of 3 parts:
Notice that the types are after the name: so name: string
instead of what we are used to in C#: string name
.
As you can see in the code in the class above : between public
and Clown()
there is no return type, furthermore the name Clown
is the same as the name of the class: that is how we know it is a constructor.
Note: code belongs in classes, not in forms!
Constructor overloading means that multiple constructors exist within a class. You can then create objects in different ways.
For example: if you know the length of a Clown you give it, otherwise you do not:
Clown oneClown = new Clown("Popov");
Clown otherClown = new Clown("Bassie", 186);
From the number of parameters and their type, the compiler then sees which constructor to execute:
public class Clown
{
// Fields <-- Fields we make private!
private string name;
private int height;
// constructors
public Clown(string name, int height)
{
this.name = name;
this.height = height;
}
public Clown(string name)
{
this.name = name;
this.height = 175; // THIS IS NOT QUITE AS WE WANT! Read on!!!
}
// methods
public string TalkAboutYourself()
{
return "My name is " + this.name
+ "and I'm " + this.height + " centimeters tall.";
}
}
You can see that a Clown whose length we do not specify in this code is given the length 175.
The above code contains something else we don’t really want: you can see that the code of the constructors is very similar. We can still optimize the constructor code:
// constructors
public Clown(string name, int height)
{
this.name = name;
this.height = height;
}
public Clown(string name) : this(name, 175)
{
}
The moment the second constructor is called, it says: this(name, 175)
: that means as much as: call from this
(myself) the constructor that expects as parameters a string and an int: use the value of name
and for the height: 175
.
Can you think of an advantage of this this
construction?
By the way, we don’t want hard-coded numbers in code, we call those magic numbers
: no idea where they come from and what they mean. For example, it is neater to create a constant
, give it a clear name, and use it:
// https://en.wikipedia.org/wiki/Average_human_height_by_country
public const int averagePersonHeight = 175;
Thus, from the call .... : this(name,averagePersonHeight)
suddenly becomes clearer what it means.
You can also see that in comments a source is mentioned! That makes it possible to check, validate and possibly improve it:
Invaders and Gallows.