4.6. Overloaded, Hidden, or Ambiguous?

Consider the following class hierarchy:

class Base
{
  public void f( int ival ){ ... }
}

class Derived : Base
{
      public void f( ref int ix ){ ... }
}

Does the definition of f() within the Derived class require a new specifier? Or, to put it in program terms, which of the following invocations, if any, result in a compile-time error?

public static void main()
{
   Derived d = new Derived;
   int ival = 1024;

   d.f( ref ival ); // OK?
   d.f( ival );     // OK?
}

The answers are (1) no, the new specifier is not required, and (2) none of the invocations result in a compile-time error. That is, the definition of f() within the Derived class does not hide the base-class instance. Within the Derived class, both instances are visible and thus able to be invoked.

Why? Recall that functions that share the same name are treated as overloaded, provided that the signatures are unique. When two members of a class or interface hierarchy share the same name and are methods, the derived instance is treated as hiding the base-class instance only if the two signatures are the same.

In our example, the two signatures are not equivalent. Two methods can be overloaded on the basis of the presence or absence of the ref parameter. In fact, we can introduce an overloaded third instance distinguished only by an out parameter.

Multiple interface inheritance leaves open the possibility of inheriting the same member name from two or more interfaces, resulting in a name ambiguity. For example, consider the following inheritance hierarchy, in which two instances of doSomething() are visible within aMed:

interface a {
   void doSomething(object o);
}

interface b {
   void doSomething(object o);
}

class aMed : a, b {
   // oops! which doSomething?
   public void doit(){ doSomething(); }
}

We can fully resolve the potential name ambiguity within the aMed class by providing explicit declarations for both inherited interface instances. In addition, we provide a synthesized instance to be used when an aMed class object is being manipulated directly—for example:

class aMed : a,b
{
    public void doSomething( string s ){ ... }

    public void a.doSomething( object o ) { ... }
    public void b.doSomething( object o ) { ... }

    // ...
}

class EntryPoint
{
    public static void Main()
    {
          aMed am = new aMed();
          am.doSomething( "OK" ); // aMed.doSomething

          a aaa = am as a;
          aaa.doSomething( am );  // aMed.a.doSomething

          b bbb = am as b;
          bbb.doSomething( am );  // aMed.b.doSomething
    }
}

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.226.133.49