Reputation: 171
I sometimes see in C# code:
An instance being created, that then invokes a constructor that is not the same as that of the type.
For example:
Person somebody = new Member();
What possible cases would this show up in, and why is it desirable?
(I thought it had to do with calling a base class constructor but I couldn't get that to compile)
Upvotes: 1
Views: 207
Reputation: 61982
Your question is not really a question about constructors. It is all about implicit conversions. In your declaration:
Person somebody = new Member();
the right-hand side of the =
operator clearly has (compile-time) type Member
. However the variable somebody
has (compile-time) type Person
. That is legal only if there exists an implicit conversion from Member
to Person
. Then the code is really like Person somebody = (Person)(new Member());
except that the "cast" is invisible.
Now, the most usual implicit conversion is the reference conversion from a class
to its (direct or indirect) base class, or to an interface that it implements.
There is a somewhat different implicit conversion, a boxing conversion from a struct
or enum
to its base class or interface.
There are also user-defined implicit conversions which are like a kind of methods (written with implicit operator
).
There are more implicit conversions, for example from a value type V
to the Nullable<>
version of it, usually written as V?
, but it would be strange if Person
was just a using
alias for Member?
, so this one is not realistic in your example. Another one that is rarely relevat in this example, is "widening" conversion from e.g. int
to long
.
Read the C# Language Specification to learn more about what conversions exist.
Upvotes: 1
Reputation: 38785
Member inherits from Person or Person is a poorly named Interface and Member implements it:
More on inheritance: http://msdn.microsoft.com/en-gb/library/ms173149(v=vs.80).aspx http://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming)
More on interfaces: http://msdn.microsoft.com/en-us/library/ms173156.aspx http://en.wikipedia.org/wiki/Protocol_(object-oriented_programming)
You could define the following using inheritance:
public class Person
{
public string Name { get; set; }
public DateTime DateOfBirth { get; set; }
}
public class Adult : Person
{
public string Workplace { get; set; }
}
public class Child : Person
{
public List<string> Toys { get; set; }
}
And then if you create an instance of Adult (Adult a = new Adult();
) you will have access to the Name, DateOfBirth and Workplace properties. Likewise with the child, you will have the Toys property.
Furthermore, you can store a list of Person which contains both adults and children:
List<Person> people = new List<Person>();
people.Add(new Adult() { Name = "Adult", DateOfBirth = DateTime.Now, Workplace = "Microsoft" });
people.Add(new Child() { Name = "Child", DateOfBirth = DateTime.Now, Toys = new List<string> { "Car", "Train" } });
and then you can go through each printing out the name and date of birth:
foreach(Person p in people)
{
Console.WriteLine(p.Name + ", " + p.DateOfBirth.ToString("dd/MMM/yy"));
if(p is Child)
{
Console.WriteLine(p.Name + " has the following toys: " + string.Join(", ", ((Child)p).Toys));
}
else if(p is Adult)
{
Console.WriteLine(p.Name + " works at " + ((Adult)p).Workplace;
}
}
Interfaces basically define a contract (i.e. an object that implements IPerson
will provide implementations for its methods). It's like an ethernet card: there is a standard for how they talk to the network but how they work internally is up to the manufacturer as long as they provide the expected behaviour. Interfaces can't have any logic in them or store any data, they simply advertise what something implementing that interface provides.
public interface IPerson
{
string Name { get; set; }
DateTime DateOfBirth { get; set; }
}
public class Adult : IPerson
{
public string Name { get; set; }
public DateTime DateOfBirth { get; set; }
public string Workplace { get; set; }
}
public class Child : IPerson
{
public string Name { get; set; }
public DateTime DateOfBirth { get; set; }
public List<string> Toys { get; set; }
}
There's also abstract classes which provide some of the functionality of interfaces but can implement some logic. The only thing to note in all of this is that a class can only be derived from (i.e. inherit from) a single class, although that class can inherit from another class. You can, however, implement multiple interfaces.
Upvotes: 3
Reputation: 18769
Member
class probably looks like this...
public class Member : Person {}
Where Member
derives from Person
.
Upvotes: 0
Reputation: 12857
This is valid if Person
is a Base class of Member
Similarly this is valid also:
Object o = new Member();
Upvotes: 2