This is the creation of a new virtual method in X, called ToString(), which hides Object.ToString(). Therefore, if you have:
Y y = new Y();
X x = y;
Object o = y;
Console.WriteLine(y.ToString());
Console.WriteLine(x.ToString());
Console.WriteLine(o.ToString());
The challenge is easy
Console.WriteLine(y);
equivalent to the final line, so the type name is printed.
, X.ToString Object.ToString():
public override String ToString()
{
return "Hi, I'm X";
}