OK, the key thing to realise is that when a method is invoked on an object we have two concepts:
1) the object being invoked
2) the reference through which it is being invoked
in C# 1) and 2) do not have to be onf the same type, they must be related, but do not have to be the same. Consider the following code:
class Foo
{
public void Quux()
{
Console.WriteLi ne("Foo:Quux") ;
}
}
class Bar : Foo
{
public void Quux()
{
Console.WriteLi ne("Bar:Quux") ;
}
}
I can now write
Foo f = new Bar();
as Foo and Bar are type compatible (related).
Now the issue is what happens when we call
f.Quux();
in this setup it will print out Foo:Quux
if we write
Bar b = new Bar();
b.Quux();
it prints out Bar:Quux
This is known as static binding and the version of the function that gets called is determined by the type of the *reference* and is determined at compile time. And in this case Bar.Quux is said to be *hiding* Foo.Quux for as far as the compiler is concerned the two Quux methods are unrelated but it is impossible to get to Foo.Quux from a Bar reference - hence *hidden*.
Lets change the code a little
class Foo
{
public virtual void Quux()
{
Console.WriteLi ne("Foo:Quux") ;
}
}
class Bar : Foo
{
public override void Quux()
{
Console.WriteLi ne("Bar:Quux") ;
}
}
Now in this case
Foo f = new Bar();
f.Quux();
outputs Bar:Quux as the, in essence, Bar.Quux has *replaced* Foo.Quux in the virtual function table for Bar objects.This is what is mean't by *overridden*. This is known as dynamic binding (not to be confused with late binding) in that the version of the function f.Quux() will call cannot be determined until runtime when the type of object f references is known.
Two last points: the first code example will compile with a warning (saying that Bar.Quux hides Foo.Quux) and to get rid of the warning V=Bar's code needs to change to this
class Bar : Foo
{
public new void Quux()
{
Console.WriteLi ne("Bar:Quux") ;
}
}
This shows that the Bar author is aware of the issue and Bar.Quux is nothing to do with Foo.Quux they just happen to have the same name (this can happen if Foo and Bar are authored and evlove independently).
The last thing is what happens with this situation:
class Foo
{
public virtual void Quux()
{
Console.WriteLi ne("Foo:Quux") ;
}
}
class Bar : Foo
{
public void Quux() // no override keyword
{
Console.WriteLi ne("Bar:Quux") ;
}
}
In this case
Foo f = new Bar();
f.Quux();
outputs Foo:Quux
This is because the derived class must *explicitly* agree to dynamic binding for it to take place. this prevents a derived mthod being called accidently when a new version of the base class ships which now has a virtual method of the same name and signature as an existing one in the derived class.
Regards
Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog
nntp://news.microsoft. com/microsoft.publi c.dotnet.langua ges.csharp/<uo************ **@TK2MSFTNGP12 .phx.gbl>
I do not understand what is meant when someone states that a given method is
"hidden" verses overriden.
Would someone please provide a short example of both cases and why you might
want to "hide" a parent method's implementation verses simply overriding it
(ie take advantage of polymorphism)?
Thanks,
TJ
---
Incoming mail is certified Virus Free.
Checked by AVG anti-virus system (
http://www.grisoft.com).
Version: 6.0.768 / Virus Database: 515 - Release Date: 22/09/2004
[microsoft.publi c.dotnet.langua ges.csharp]