15.02.2015 Views

C# 4 and .NET 4

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

implementation inheritance ❘ 97<br />

So far, this code works fine. One way to mess up the progression through the hierarchy of constructors,<br />

however, is to declare a constructor as private:<br />

private GenericCustomer()<br />

{<br />

name = "";<br />

}<br />

If you try this, you’ll find you get an interesting compilation error, which could really throw you if you don’t<br />

underst<strong>and</strong> how construction down a hierarchy works:<br />

'Wrox.ProCSharp.GenericCustomer.GenericCustomer()’ is inaccessible due to its protection level<br />

The interesting thing is that the error occurs not in the GenericCustomer class, but in the derived class,<br />

Nevermore60Customer. What’s happened is that the compiler has tried to generate a default constructor<br />

for Nevermore60Customer but has not been able to because the default constructor is supposed to invoke<br />

the no-parameter GenericCustomer constructor. By declaring that constructor as private, you’ve made<br />

it inaccessible to the derived class. A similar error occurs if you supply a constructor to GenericCustomer,<br />

which takes parameters, but at the same time you fail to supply a no-parameter constructor. In this case,<br />

the compiler will not generate a default constructor for GenericCustomer, so when it tries to generate<br />

the default constructors for any derived class, it will again find that it can’t because a no-parameter base<br />

class constructor is not available. A workaround would be to add your own constructors to the derived<br />

classes — even if you don’t actually need to do anything in these constructors — so that the compiler doesn’t<br />

try to generate any default constructors for them.<br />

Now that you have all the theoretical background you need, you’re ready to move on to an example of how<br />

you can neatly add constructors to a hierarchy of classes. In the next section, you start adding constructors<br />

that take parameters to the MortimerPhones example.<br />

adding Constructors with Parameters to a Hierarchy<br />

You’re going to start with a one-parameter constructor for GenericCustomer, which specifies that<br />

customers can be instantiated only when they supply their names:<br />

abstract class GenericCustomer<br />

{<br />

private string name;<br />

public GenericCustomer(string name)<br />

{<br />

this.name = name;<br />

}<br />

So far, so good. However, as mentioned previously, this will cause a compilation error when the compiler<br />

tries to create a default constructor for any derived classes because the default compiler-generated<br />

constructors for Nevermore60Customer will try to call a no-parameter GenericCustomer constructor,<br />

<strong>and</strong> GenericCustomer does not possess such a constructor. Therefore, you’ll need to supply your own<br />

constructors to the derived classes to avoid a compilation error:<br />

class Nevermore60Customer: GenericCustomer<br />

{<br />

private uint highCostMinutesUsed;<br />

public Nevermore60Customer(string name)<br />

: base(name)<br />

{<br />

}<br />

Now instantiation of Nevermore60Customer objects can occur only when a string containing the<br />

customer’s name is supplied, which is what you want anyway. The interesting thing is what the<br />

Nevermore60Customer constructor does with this string. Remember that it can’t initialize the name field<br />

itself because it has no access to private fields in its base class. Instead, it passes the name through to the<br />

base class for the GenericCustomer constructor to h<strong>and</strong>le. It does this by specifying that the base class<br />

www.it-ebooks.info

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!