Additional Class Member Topics


Now that you've covered the basics of member definition, it's time to look at some more advanced member topics. In this section, you look at:

  • Hiding base class methods

  • Calling overridden or hidden base class methods

  • Nested type definitions

Hiding Base Class Methods

When you inherit a (nonabstract) member from a base class, you also inherit an implementation. If the inherited member is virtual, you can override this implementation with the override keyword. Regardless of whether the inherited member is virtual, you can, if you want to, hide the implementation. This is useful when, for example, a public inherited member doesn't work quite as you want it to.

You can do this simply by using code such as:

 public class MyBaseClass { public void DoSomething() { // Base implementation. } } public class MyDerivedClass : MyBaseClass { public void DoSomething() { // Derived class implementation, hides base implementation. } } 

Although this code works fine, it will generate a warning that you are hiding a base class member. This gives you the chance to correct things if you have accidentally hidden a member that you actually want to use. If you really do want to hide the member, you can say explicitly that this is what you want to do using the new keyword:

public class MyDerivedClass : MyBaseClass { new public void DoSomething()    {       // Derived class implementation, hides base implementation.    } }

This will work in exactly the same way, but won't show a warning.

At this point, it is worth pointing out the difference between hiding and overriding base class members. Consider the following code:

public class MyBaseClass { public virtual void DoSomething()    { Console.WriteLine("Base imp");    } }     public class MyDerivedClass : MyBaseClass { public override void DoSomething()    { Console.WriteLine("Derived imp");    } }

Here, the overriding method replaces the implementation in the base class, such that the following code will use the new version, even though it does so through the base class type (using polymorphism):

 MyDerivedClass myObj = new MyDerivedClass(); MyBaseClass myBaseObj; myBaseObj = myObj; myBaseObj.DoSomething(); 

This gives the output:

Derived imp

Alternatively, you could hide the base class method instead, using:

public class MyBaseClass {    public virtual void DoSomething()    {       Console.WriteLine("Base imp");    } }     public class MyDerivedClass : MyBaseClass { new public void DoSomething()    {       Console.WriteLine("Derived imp");    } }

The base class method needn't be virtual for this to work, but the effect is exactly the same and the preceding code only requires changes to one line of code. The result, for a virtual or nonvirtual base class method, is the following:

Base imp

Although the base implementation is hidden, you still have access to it through the base class.

Calling Overridden or Hidden Base Class Methods

Whether you override or hide a member, you still have access to the base class member from the derived class. There are many situations in which this can be useful, for example:

  • When you want to hide an inherited public member from users of a derived class but still want access to its functionality from within the class.

  • When you want to add to the implementation of an inherited virtual member rather than simply replacing it with a new overridden implementation.

To achieve this, you can use the base keyword, which refers to the implementation of the base class that is contained within a derived class (in a similar way to its use in controlling constructors, as you saw in the last chapter), for example:

 public class MyBaseClass { public virtual void DoSomething() { // Base implementation. } } public class MyDerivedClass : MyBaseClass { public override void DoSomething() { // Derived class implementation, extends base class implementation. base.DoSomething(); // More derived class implementation. } } 

This code executes the version of DoSomething() contained in MyBaseClass, the base class of MyDerivedClass, from within the version of DoSomething() contained in MyDerivedClass.

As base works using object instances it is an error to use it from within a static member.

The this Keyword

As well as using base in the last chapter you also used the this keyword. As with base, this can also be used from within class members, and, like base, this keyword refers to an object instance. The object instance referred to by this is the current object instance (which means that you can't use this keyword in static members, because static members are not part of an object instance).

The most useful function of the this keyword is the ability to pass a reference to the current object instance to a method, for example:

 public void doSomething() { MyTargetClass myObj = new MyTargetClass(); myObj.DoSomethingWith(this); } 

Here, the MyTargetClass that is instantiated has a method called DoSomethingWith(), which takes a single parameter of a type compatible with the class that contains the preceding method. This parameter type might be of this class type, a class type that is inherited by this class, an interface implemented by the class, or (of course) System.Object.

Nested Type Definitions

As well as defining types such as classes in namespaces, you can also define them inside other classes. If you do this, then you can use the full range of accessibility modifiers for the definition, rather than just public and internal, and you may also use the new keyword to hide a type definition inherited from a base class.

For example, the following code defining MyClass also defines a nested class called myNestedClass:

 public class MyClass { public class myNestedClass { public int nestedClassField; } } 

If you want to instantiate myNestedClass from outside MyClass, you must qualify the name, for example:

 MyClass.myNestedClass myObj = new MyClass.myNestedClass(); 

However, you may not be able to do this at all if the nested class is declared as private or another accessibility level that is incompatible with the code at the point at which this instantiation is performed.

The main reason for the existence of this feature is to define classes that are private to the containing class, so that no other code in the namespace has access to them.




Beginning Visual C# 2005
Beginning Visual C#supAND#174;/sup 2005
ISBN: B000N7ETVG
EAN: N/A
Year: 2005
Pages: 278

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net