Overlap vs. method hiding

I am a bit confused about overriding and hiding a method in C #. The practical use of each of them will also be evaluated, as well as an explanation of when each will use each.

I am confused about redefinition - why do we redefine? What I have learned so far is that, by overloading, we can provide the desired implementation to the derived class method without changing the signature.

If I do not override the method of the superclass, and I make changes to the method in the subclass, will the changes be made to the method of the superclass?

I am also confused about the following: what does this demonstrate?

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(); // what this will print and why? b = a; // what happens here? } 
+41
override c #
01 Oct 2018-10-10 at
source share
3 answers

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 a classic OO method in which a derived class can have more specific behavior than a base class (in some languages ​​you have no choice but to do this). When a virtual method is called on an object, the most derived version of the method is called. Therefore, although we are dealing with isReallyDerived as a BaseClass , then the functionality defined in DerivedClass .

Hiding means that we have a completely different method. When we call WriteNum() on isReallyDerived , then there is no way to find out that DerivedClass has another WriteNum() , so it is not called. It can only be called when we are dealing with an object as a DerivedClass .

In most cases, hiding is bad. Typically, either you should have the method as virtual if you can change it in a derived class and override it in a derived class. There are, however, two things that are useful for:

  • Future compatibility. If DerivedClass had a DoStuff() method, and then later BaseClass was modified to add a DoStuff() method (remember that they can be written by different people and exist in different assemblies), then a ban on hiding a member would suddenly make DerivedClass buggy without it changes. In addition, if the new DoStuff() on BaseClass was virtual, then automatically doing it on DerivedClass overriding it may lead to calling an existing method when it should not. Therefore, it is good that hiding is the default value (we use new to understand that we definitely want to hide, but leave it hidden and issue a warning when compiling).

  • Covariance of the poor. Consider the Clone() method on BaseClass , which returns a new BaseClass instance of the created one. In an override on DerivedClass this will create a DerivedClass , but return it as a BaseClass , which is not so useful. We can do this to override the virtual protected CreateClone() . In BaseClass we have a Clone() that returns the result of this - and all is well - in DerivedClass we hide it with a new Clone() that returns a DerivedClass . Calling Clone() on BaseClass will always return a BaseClass reference that matches the value of BaseClass or DerivedClass . Calling Clone() on the DerivedClass will return the DerivedClass value that we want in this context. There are other options for this principle, but it should be noted that they are all quite rare.

It is important to note that we used hidden text to delete for the calling code, since a person using DerivedClass can reasonably expect its Clone() to return a DerivedClass . The results of any of the methods that could be called are supported with each other. In most cases, the risk of unexpected surprises is hidden, so they are usually unhappy. This is justified precisely because it solves the very problem that is often hidden.

In general, hiding is sometimes necessary, rarely useful, but generally poor, so be very careful.

+98
01 Oct '10 at 11:22
source share

Overriding is when you provide a new implementation of a method override 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, if that method is not defined as virtual in the base class, or when your new implementation does not specify override .

Concealment is very often bad; you should try not to, if you can avoid it at all. Hiding can cause unexpected events, since hidden methods are used only when calling a variable of the actual type that you defined, and not using a reference to the base class ... on the other hand, virtual methods that are overridden call the correct version of the method, even if it is called using a base class reference in a child class.

For example, consider these classes:

 public class BaseClass { public virtual void Method1() //Virtual method { Console.WriteLine("Running BaseClass Method1"); } public void Method2() //Not a virtual method { Console.WriteLine("Running BaseClass Method2"); } } public class InheritedClass : BaseClass { public override void Method1() //Overriding the base virtual method. { Console.WriteLine("Running InheritedClass Method1"); } public new void Method2() //Can't override the base method; must 'new' it. { Console.WriteLine("Running InheritedClass Method2"); } } 

Call like this using an InheritedClass instance in the appropriate link:

 InheritedClass inherited = new InheritedClass(); inherited.Method1(); inherited.Method2(); 

This returns what you expect; both methods say they use versions of InheritedClass.

Running the InheritedClass1 Method
Running the InheritedClass2 Method

This code creates an instance of the same InheritedClass, but stores it in a BaseClass link:

 BaseClass baseRef = new InheritedClass(); baseRef.Method1(); baseRef.Method2(); 

Usually, in accordance with the principles of OOP, you should expect the same result as in the above example. But you will not get the same result:

Running the InheritedClass1 Method
Running the BaseClass2 Method

When you wrote the InheritedClass code, you probably needed all the calls to Method2() to run the code you wrote in it. This will usually be the way it works - if you are working with the virtual method that you redefined. But since you are using the new / hidden method, it instead invokes the version for the link you are using.




If this behavior is really what you need; there you go. But I would strongly suggest that if this is what you want, there might be a big architecture problem with the code.

+23
Oct 01 '10 at 11:12
source share

Method overriding is simply overriding the standard implementation of a base class method in a derived class.

Method hiding: you can use the 'new' keyword before the virtual method in the derived class

as

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

Now, if you create another class Bar1, which is derived from Bar, you can override foo1, which is in the bar.

+2
01 Oct '10 at 11:13
source share



All Articles