views:

120

answers:

4

Possible Duplicate:
Overloading,Overriding and Hiding?

i am a bit confuse with the overriding vs hiding a method in C# so some bodu could please elaborate me on this please ... also the practical use knowledge of these will be appreciated

and in what situation we my feel need of this?

Even i am confuse with overriding why do we do overriding what i have learnt that by doing overring we can provide desired implementation to a method of derived class... does that only intention to fix the signature .. also confuse on if i dont override the method of super class and i make changes to the method of inheriteed super class method usng the sub class object will that make commit changes to the super class method ?

and i am also confuse with this what is this?

class A
{
virtual m1()
{
console.writeline("Bye to all");
}
}
class B:A
{
override m1()
{
console.writeLine("Hi to all");
}
}
class C
{
A a =new A();
B b=new B();
a=b;(what is this)
a.m1(); // wat this will print and why

and what is if i do b=a;


}
+4  A: 

Overriding is when you provide a new implementation of a method in a descendant class when that method is defined in the base class as virtual.

Hiding is when you provide a new implementation of a method in a descendant class when that method is not defined in the base class as virtual.

Hiding is bad; you should try to never do it. You would be most likely to do it when you do not have the source code of a class you are inheriting from, and for some reason you need a method to work differently than it does.

But hiding can cause unexpected things to happen, because Hidden methods are only used when called on a variable of the actual type you defined, not if using a base class reference... on the other hand, Virtual methods which are overridden will end up with the proper method version being called, even when called using the base class reference on a child class.

Andrew Barber
I wouldn't say you should _never_ hide a method. Sometimes, I find hiding very useful (for, say, changing the return value to a subclass)
thecoop
That's why I said you should -try- to never do it :)
Andrew Barber
Yes, but in case @thecoop mentions you want to very deliberately try to hide. The main thing I think is that normally hiding can introduce nasty surprises, but in using it for covariance you actually remove surprises.
Jon Hanna
+1  A: 

Method Overriding is simpley override a default implementation of a base class method in the derived class.

Method Hiding : You can make use of 'new' keyword before a virtual method in a derived class

as

class Foo  
{  
  public virtual void foo1()  
  {  

  }  
}  

class Bar:Foo  
{  
  public new virtual void foo1()  
  {   

  }  
}  

now if you make another class Bar1 which is derived from Bar , you can override foo1 which is defind in Bar.

saurabh
y can ti use virtual with override key word if in your example i do....class myclass:bar{ then it will get the Foo class foo1() or bar class foo1() to override it} also if in bar class insted of hiding the foo1() i override it and i put virtual before it then will it be inherited to myClass and again by puting override can i override the method of Bar class foo1() to myClass
NoviceToDotNet
@NoviceToDotNet No, virtual can be used in a class derived from Bar, but it will override Bar.foo1 and not Foo.foo1. The above mixture of hiding and virtual is valid, though in combining the two together perhaps not the best explanation of the difference between the two.
Jon Hanna
+1  A: 

Consider:

public class BaseClass
{
  public void WriteNum()
  {
    Console.WriteLine(12);
  }
  public virtual void WriteStr()
  {
    Console.WriteLine("abc");
  }
}

public class DerivedClass : BaseClass
{
  public new void WriteNum()
  {
    Console.WriteLine(42);
  }
  public override void WriteStr()
  {
    Console.WriteLine("xyz");
  }
}
/* ... */
BaseClass isReallyBase = new BaseClass();
BaseClass isReallyDerived = new DerivedClass();
DerivedClass isClearlyDerived = new DerivedClass();

isReallyBase.WriteNum(); // writes 12
isReallyBase.WriteStr(); // writes abc
isReallyDerived.WriteNum(); // writes 12
isReallyDerived.WriteStr(); // writes xyz
isClearlyDerived.WriteNum(); // writes 42
isClearlyDerived.writeStr(); // writes xyz

Overriding is the classic OO way in which a derived class can have more specific behaviour than a base class (in some languages you've no choice but to do so). When a virtual method is called on an object, then the most derived version of the method is called. Hence even though we are dealing with isReallyDerived as a BaseClass then functionality defined in DerivedClass is used.

Hiding means that we have a completely different method. When we call WriteNum() on isReallyDerived then there's no way of knowing that there is a different WriteNum() on DerivedClass so it isn't called. It can only be called when we are dealing with the object as a DerivedClass.

Most of the time hiding is bad. Generally, either you should have a method as virtual if its likely to be changed in a derived class, and override it in the derived class. There are however two things it is useful for:

  1. Forward compatibility. If DerivedClass had a DoStuff() method, and then later on BaseClass was changed to add a DoStuff() method, (remember that they may be written by different people and exist in different assemblies) then a ban on member hiding would have suddenly made DerivedClass buggy without it changing. Also, if the new DoStuff() on BaseClass was virtual, then automatically making that on DerivedClass an override of it could lead to the pre-existing method being called when it shouldn't. Hence it's good that hiding is the default (we use new to make it clear we definitely want to hide, but leaving it out hides and emits a warning on compilation).

  2. Poor-man's covariance. Consider a Clone() method on BaseClass that returns a new BaseClass that's a copy of that created. In the override on DerivedClass this will create a DerivedClass but return it as a BaseClass, which isn't as useful. What we could do is to have a virtual protected CreateClone() that is overridden. In BaseClass we have a Clone() that returns the result of this - and all is well - in DerivedClass we hide this with a new Clone() that returns a DerivedClass. Calling Clone() on BaseClass will always return a BaseClass reference, which will be a BaseClass value or a DerivedClass value as appropriate. Calling Clone() on DerivedClass will return a DerivedClass value, which is what we'd want in that context. There are other variants of this principle, however it should be noted that they are all pretty rare.

An important thing to note with the second case, is that we've used hiding precisely to remove surprises to the calling code, as the person using DerivedClass might reasonably expect its Clone() to return a DerivedClass. The results of any of the ways it could be called are kept consistent with each other. Most cases of hiding risk introducing surprises, which is why they are generally frowned upon. This one is justified precisely because it solves the very problem that hiding often introduces.

In all, hiding is sometimes necessary, infrequently useful, but generally bad, so be very wary of it.

Jon Hanna
sir what if i use public virtual void WriteNum() and in sub claass .....i use public new virual void WriteNum()what method will be called on isReallyBase.WriteNum(); and y
NoviceToDotNet
@NoviceToDotNet using `new virtual` means it hides the more derived version, but can itself be virtual. If you call `WriteNum()` on either `isReallyBase` or `isReallyDerived` then the version defined in `BaseClass` would be called, as it isn't overriden, but if you called it on `isClearlyDerived` then the hiding version will be called. Further, you could have an override in a further subclass (say "`DerivedFromDerivedClass`") and this override would be called when `DerivedFromDerivedClass` is manipulated through a `DerivedFromDerivedClass` variable or a `DerivedClass` variable...
Jon Hanna
and also in case if we dot't override the method of super class bcas it's not compulsory then what it will do isReallyDerived.WriteStr();
NoviceToDotNet
... but if the `DerivedFromDerivedClass` had it invoked through a `BaseClass` variable, then only that defined in `BaseClass` would be called. One way to think about it is that base classes "know" that virtual members can be overridden (and override members can be overridden again), and will "look" for those overrides, but they can't "see past" any hiding members.
Jon Hanna
thanks your explanation helped me to large extent sir...thanks a lot
NoviceToDotNet
sir 1 confusion u told "When a virtual method is called on an object, then the most derived version of the method is called. "...............then y isReallyBase.WriteStr(); // writes abc .. ......not prinithing writes xyz
NoviceToDotNet
isReallyBase **is** a BaseClass (`BaseClass isReallyBase = new BaseClass();`) so what happens in DerivedClass has nothing to do with it.
Jon Hanna
and also u told it look 4 most derived class it means if have a class..myclass:derived class and it has mehod overriding public override void WriteStr(){some code}then isReallyDerived.WriteStr(); will call code written in myclass method?
NoviceToDotNet
isReallyDerived will call the version defined in DerivedClass because that's the most derived version applicable to something created with `new DerivedClass()` but if we did `isReallyDerived = new MyClass()` then the version defined in MyClass would be called.
Jon Hanna