Inheritance and hiding

P

Peter K

Hi

I have a class A which implements interface IUserDal, which has several
public methods. None of these methods are declared
virtual.

public class A : IUserDal

There is also a client C, which uses A (but only knows A via the interface
IUserDal).

Now I want to extend A with class B - where I want to change/override only
one of the methods - GetUsername().

public class B : A
(and in class B I declare a new method "GetUsername()").

I can't really "override" the method, but I can "hide" it. The strange thing
is (at least to me) that with the above definitions, the client C still
calls the GetUsername method in the A class.

For example:
IUserDal dal = new B();
string s = dal.GetUsername();

will actually call the method in class A.

However, if I change B, so it looks like:

public class B : A, IUserDal

then the GetUsername method in B is called.

Why is this?


Thanks,
Peter
 
A

Alberto Poblacion

Peter K said:
I have a class A which implements interface IUserDal, which has several
public methods. None of these methods are declared
virtual.

public class A : IUserDal

There is also a client C, which uses A (but only knows A via the interface
IUserDal).

Now I want to extend A with class B - where I want to change/override only
one of the methods - GetUsername().

public class B : A
(and in class B I declare a new method "GetUsername()").

I can't really "override" the method, but I can "hide" it. The strange
thing is (at least to me) that with the above definitions, the client C
still calls the GetUsername method in the A class.

For example:
IUserDal dal = new B();
string s = dal.GetUsername();

will actually call the method in class A.

However, if I change B, so it looks like:

public class B : A, IUserDal

then the GetUsername method in B is called.

Why is this?


In the first case, you are trying to use polymorphism, that is, you call
the method in the parent class (via the interface) and you expect the method
in the child class to be executed. However, since you have hidden the method
rather than overriding it, the polymorphism chain is broken and you invoke
the method directly referred to by the interface (the one in the parent
class).

When you implement the interface in the child class, you are not using
inheritance at all on that method. When your client C invokes it, it is
calling directly the method in class B through the interface, and the method
in class A is simply ignored.
 
P

proxyuser

Peter K said:
Hi

I have a class A which implements interface IUserDal, which has several
public methods. None of these methods are declared
virtual.

public class A : IUserDal

There is also a client C, which uses A (but only knows A via the interface
IUserDal).

Now I want to extend A with class B - where I want to change/override only
one of the methods - GetUsername().

public class B : A
(and in class B I declare a new method "GetUsername()").

I can't really "override" the method, but I can "hide" it. The strange
thing is (at least to me) that with the above definitions, the client C
still calls the GetUsername method in the A class.

For example:
IUserDal dal = new B();
string s = dal.GetUsername();

will actually call the method in class A.

However, if I change B, so it looks like:

public class B : A, IUserDal

then the GetUsername method in B is called.

Why is this?

The compiler can't necessariy know the type of something when inheritance is
used. For example if you wrote a function

void foo(IUserDal x)
{
string s = x.GetUsername();
}

What is the compiler supposed to call here? If the calling code were
foo(new B());

then it's supposed to call the hidden function on B, but the compiler can't
know where that call is coming from (it could be third party code that
hasn't even been written yet.) So it has to make a decision on how to pick
the right function. Since the function isn't virtual, then obviously the
compiler can't generate the code to make a dynamic call at run time. It has
to figure out something to do right. This would be the same as if you had
done

void foo(A x)
{
string s = x.GetUsername();
}

The compiler has little choice but to pick the implementation for A in that
case. If you were the compiler writer, how would you handle that scenario?
Now, you might say that the compiler should know that you reall meant to use
B, since you instantiated a new B right there in the code. You have a
point, but how far is the compiler supposed to go to figure out what the
type is? And then should it have a different rule to use if it can't figure
it out? I think it would be super confusing if it used the method for B in
your code, but the method for A in my code where it couldn't figure out who
the caller was.
 
P

Peter K

proxyuser said:
The compiler can't necessariy know the type of something when inheritance
is used. For example if you wrote a function

void foo(IUserDal x)
{
string s = x.GetUsername();
}

What is the compiler supposed to call here? If the calling code were
foo(new B());

In one of my cases, the call will be made to A.GetUsername(), in the other
case the call will be made to B.GetUsername().

Somehow, the simple addition of the interface IUserDal to the declaration of
the class B makes all the difference.


/Peter
 
P

Peter Duniho

In one of my cases, the call will be made to A.GetUsername(), in the
other
case the call will be made to B.GetUsername().

Somehow, the simple addition of the interface IUserDal to the
declaration of
the class B makes all the difference.

Even though your methods are not declared as "virtual", interface
implementations are basically virtual anyway. If class B doesn't
implement the interface, then a method of the same name in the method
isn't virtual and thus winds up hiding the virtual method in the base
class, rather than being part of the implementation of the interface.

But, if you declare B as implementing the same interface, then
implementation members of the class wind up with the same implied virtual
attribute for the class B member implementing the interface. Thus, when
you have an object B, used via the interface it implements, you
automatically get the expected behavior.

Pete
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top