cannot understand what method hiding exactly do 'behind the scenes' - c#

i find it hard to understand exactly what method hiding does.
can somebody please explain me what is going on 'behind the scenes' while using method hiding?
class Base
{
public virtual void OverrideMethod()
{
Console.WriteLine("Base.OverrideMethod");
}
public virtual void HideMethod()
{
Console.WriteLine("Base.HideMethod");
}
}
class Derived:Base
{
public override void OverrideMethod()
{
Console.WriteLine("Derived.OverrideMethod");
}
public new void HideMethod()
{
Console.WriteLine("Derived.HideMethod");
}
}
(1) what does this really do?
Base x=new Derived();
(2) what does these really do?
x.OverrideMethod();
x.HideMethod();
thank you in advance :)

There is hiding and there is overriding. Both are opposites. Personally I keep forgetting hiding aside from thinking "this is not overriding, better not to mix those up". I can not remember a single case where I used it. If I ever can not override, I just encapsulate rather then deal with hiding. So it might well be one of those things someone thought up way back, but never quite took tracktion.
Overriding changes the implementation. It must be explicitly allowed by the baseclass (virtual). It must explicitly be done by the derived class. But in turn the override takes precedence even if class is cast to a base type. Example: Object.ToString(). Code like Console.WriteLine has overloads that just accept a bunch of Objects. But since you can not print Objects, it jsut calls it's ToString() Method.
Hiding does not change the Implementation. It only hides it. As long as you do not cast it to a more basic type, you will have the Hiding Implementation hide the baseclass one. But once you cast down, the baseclass implementation asserts itself. In turn no "allowance" is nessesary.

Related

Why is it required to have override keyword in front of abstract methods when we implement them in a child class?

When we create a class that inherits from an abstract class and when we implement the inherited abstract class why do we have to use the override keyword?
public abstract class Person
{
public Person()
{
}
protected virtual void Greet()
{
// code
}
protected abstract void SayHello();
}
public class Employee : Person
{
protected override void SayHello() // Why is override keyword necessary here?
{
throw new NotImplementedException();
}
protected override void Greet()
{
base.Greet();
}
}
Since the method is declared abstract in its parent class it doesn't have any implementation in the parent class, so why is the keyword override necessary here?
When we create a class that inherits from an abstract class and when we implement the inherited abstract class why do we have to use the override keyword?
"Why?" questions like this can be hard to answer because they are vague. I'm going to assume that your question is "what arguments could be made during language design to argue for the position that the override keyword is required?"
Let's start by taking a step back. In some languages, say, Java, methods are virtual by default and overridden automatically. The designers of C# were aware of this and considered it to be a minor flaw in Java. C# is not "Java with the stupid parts taken out" as some have said, but the designers of C# were keen to learn from the problematic design points of C, C++ and Java, and not replicate them in C#.
The C# designers considered overriding to be a possible source of bugs; after all, it is a way to change the behaviour of existing, tested code, and that is dangerous. Overriding is not something that should be done casually or by accident; it should be designed by someone thinking hard about it. That's why methods are not virtual by default, and why you are required to say that you are overriding a method.
That's the basic reasoning. We can now go into some more advanced reasoning.
StriplingWarrior's answer gives a good first cut at making a more advanced argument. The author of the derived class may be uninformed about the base class, may be intending to make a new method, and we should not allow the user to override by mistake.
Though this point is reasonable, there are a number of counterarguments, such as:
The author of a derived class has a responsibility to know everything about the base class! They are re-using that code, and they should do the due diligence to understand that code thoroughly before re-using it.
In your particular scenario the virtual method is abstract; it would be an error to not override it, and so it is unlikely that the author would be creating an implementation by accident.
Let's then make an even more advanced argument on this point. Under what circumstances can the author of a derived class be excused for not knowing what the base class does? Well, consider this scenario:
The base class author makes an abstract base class B.
The derived class author, on a different team, makes a derived class D with method M.
The base class author realizes that teams which extend base class B will always need to supply a method M, so the base class author adds abstract method M.
When class D is recompiled, what happens?
What we want to happen is the author of D is informed that something relevant has changed. The relevant thing that has changed is that M is now a requirement and that their implementation must be overloaded. D.M might need to change its behaviour once we know that it could be called from the base class. The correct thing to do is not to silently say "oh, D.M exists and extends B.M". The correct thing for the compiler to do is fail, and say "hey, author of D, check out this assumption of yours which is no longer valid and fix your code if necessary".
In your example, suppose the override was optional on SayHello because it is overriding an abstract method. There are two possibilities: (1) the author of the code intends to override an abstract method, or (2) the overriding method is overriding by accident because someone else changed the base class, and the code is now wrong in some subtle way. We cannot tell these possibilities apart if override is optional.
But if override is required then we can tell apart three scenarios. If there is a possible mistake in the code then override is missing. If it is intentionally overriding then override is present. And if it is intentionally not overriding then new is present. C#'s design enables us to make these subtle distinctions.
Remember compiler error reporting requires reading the mind of the developer; the compiler must deduce from wrong code what correct code the author likely had in mind, and give an error that points them in the correct direction. The more clues we can make the developer leave in the code about what they were thinking, the better a job the compiler can do in reporting errors and therefore the faster you can find and fix your bugs.
But more generally, C# was designed for a world in which code changes. A great many features of C# which appear "odd" are in fact there because they inform the developer when an assumption that used to be valid has become invalid because a base class changed. This class of bugs is called "brittle base class failures", and C# has a number of interesting mitigations for this failure class.
It's to specify whether you're trying to override another method in the parent class or create a new implementation unique to this level of the class hierarchy. It's conceivable that a programmer might not be aware of the existence of a method in a parent class with exactly the same signature as the one they create in their class, which could lead to some nasty surprises.
While it's true that an abstract method must be overridden in a non-abstract child class, the crafters of C# probably felt it's still better to be explicit about what you're trying to do.
Because abstract method is a virtual method with no implementation, per C# language specification, means that abstract method is implicitly a virtual method. And override is used to extend or modify the abstract or virtual implementation, as you can see here
To rephrase it a little bit - you use virtual methods to implement some kind of late binding, whereas abstract methods force the subclasses of the type to have the method explicitly overridden. That's the point, when method is virtual, it can be overridden, when it's an abstract - it must be overriden
To add to #StriplingWarrior's answer, I think it was also done to have a syntax that is consistent with overriding a virtual method in the base class.
public abstract class MyBase
{
public virtual void MyVirtualMethod() { }
public virtual void MyOtherVirtualMethod() { }
public abstract void MyAbtractMethod();
}
public class MyDerived : MyBase
{
// When overriding a virtual method in MyBase, we use the override keyword.
public override void MyVirtualMethod() { }
// If we want to hide the virtual method in MyBase, we use the new keyword.
public new void MyOtherVirtualMethod() { }
// Because MyAbtractMethod is abstract in MyBase, we have to override it:
// we can't hide it with new.
// For consistency with overriding a virtual method, we also use the override keyword.
public override void MyAbtractMethod() { }
}
So C# could have been designed so that you did not need the override keyword for overriding abstract methods, but I think the designers decided that would be confusing as it would not be consistent with overriding a virtual method.

Inheritance and Overriding. How it differs in C#?

One thing i need to be clear. When using inheritance i can override a method without using any virtual or override keyword. My program also running and giving correct output. Then why do we have override concept even though we have inheritance. How it differs?
here is my code
class InheritanceDemo
{
public void Mymeth()
{
Console.WriteLine("this is base");
}
}
class A1 : InheritanceDemo
{
public void Mymeth()
{
Console.WriteLine("this is derived");
}
}
Main method:
static void Main(string[] args)
{
InheritanceDemo a = new A1();
A1 b = new A1();
a.Mymeth();
b.Mymeth();
}
output:
this is base
this is derived
Function overriding is needed when the derived class function has to do more or different job than the base class function.
These concepts becomes important in large scale application where problem is big so, u first create an abstract class (which just gives the ideas about how things might be rather than the direct implementation). These Abstract class can contain virtual methods (member functions) that any member of group working on has to implement (as virtual methods have to be defined in the derived class).
I think u got my point... :)
Why do you think the output is "correct"? With inheritance you want to call the correct inherited function and not a method in your base class. And that's what you define with virtual/override.
When you compiled this you should have got a warning CS0108.
Do not ignore warnings. Indeed, if you can set your compilation to error rather than warn. Warnings are generally a sign that you've done something bad or at best unclear. They aren't errors because you might have a good reason for doing something that looks bad or unclear at first look, but in the case of hiding instead of overriding we have new.
What you have here is not an override, though as you seem to expect, generally what you would want here is an override. That's part of why this code produces a compiler warning.
My program also running and giving correct output
Maybe it's correct, but it's not correct if you expected an override. If it was overriding you should have "this is derived" output by both.
If it is correct, it's a bad design, because people generally expect overrides. You can stop the warning by changing A1.Mymeth to be defined as public new void Mymeth() which is a way to flag "I really meant to do this thing that looks wrong", but if you have to explain yourself, that's a bad sign. Hiding methods is generally only to be done when someone changing a base class under you forces your hand, you need to match names due to some sort of interoperability and a small number of other very rare cases.

C# method that can optionally be implemented by subclass, without a base method

I have Code OCD, so bear with me.
We have a base class with:
virtual protected void OnHierarchyInitialized()
{
}
Now when someone overrides this method, they almost are to be expected to call the base method:
protected override void OnHierarchyInitialized()
{
base.OnHierarchyInitialized();
}
But.. nothing is happening in the base method. Nor will in the future. I just don't want people that subclass need to 'worry' when and if they need to call the base method.
Plus: this is ugly fat in the implementing code, that distracts from the rest of the code that looks like a C# version of the Mona Lisa itself.
Of course I could make it an abstract method, but here is the big disadvantage that it needs to be implemented. Also screws up my work of art.
Question
Is there something in between a virtual and abstract method, that tells the message:
override me optionally, but there is no base method to call ?
Thanks in advance!
Pretty sure the only thing you can do is use the built in XML documentation to notify the callers. For example, this is how it would show up to the person overriding your method:
There is no keyword in c# to do that. virtual is the best there is for this approach.
Just don't worry about if there is an base class implementation or not. The one implementing the derived class shouldn't worry about it.
There is just one question: Does the current implementation totally replace the base class's implementation?
If it does, don't call the base class. If it doesn't: call it.
If your code looks like this:
public void Foo()
{
// do something
OnHierarchyInitialized();
// do something else
}
You may want to consider events instead of inheritance:
public event EventHandler HierarchyInitialized = delegate { };
OnHierarchyInitialized();
public void Foo()
{
// do something
OnHierarchyInitialized(new EventArgs());
// do something else
}
private void OnHierarchyInitialized(EventArgs e)
{
EventHandler handler = HierarchyInitialized;
handler(this, e);
}
Where consumers can then subscribe to the HierarchyInitialized event when they're interested in it.
If you're absolutely sure that the base method will never actually do anything, then an abstract method is exactly the right approach. I know you say this will screw up your work of art, but think about it like this: you want a way to explicitly tell the user that the base method does nothing. An abstract method will accomplish this, whilst reminding them that the method is there, even if they choose not to use it.
Think about how interfaces work - they are a collection of abstract methods that do nothing but have to be overridden. This is the correct approach, and compliments your work of art by enforcing the inclusion of the method. The empty method shows the user that they can hook into the OnHierarchyInitialized method to achieve something.

C# prevent base class method from being hidden by new modifier in the derived class

Here's my situation. In Java I can mark a method as final in the base/super class and there is no way a derived class can mask a method of the same signature. In C# however, the new keyword allows someone inheriting my class to create a method with the same signature.
See my example below. I need to keep the orignal.MyClass public so please don't suggest that as an answer. This seems to be a lost feature moving from Java to C#:
public class orignal.MyClass{
public void MyMethod()
{
// Do something
}
}
class fake.MyClass: orignal.MyClass {
// How to prevent the following
public new void MyMethod()
{
// Do something different
}
}
EDIT: Not a duplicate.
All answers seem to suggest, it's not possible to prevent a method from being hidden/shadowed in a derived class. This became apparent while migrating some old Java code to C#. A final method in Java will not let anybody use the same method signature in any derived class. While it's great in most scenarios that C# allows a method of same signature in the derived class, it would have been great to prevent such a behavior if warranted.
// How to prevent the following
There is no way to prevent this. It's allowed by the language.
Note that, in practice, this rarely matters. If you expect your base class to be used as your class, your method will still be called. Using new only hides the method when using the DerivedClass from a a variable declared as DerivedClass.
This means that your API, if built around MyClass, will always still call MyMethod when instances are passed into your methods.
Edit in response to comments:
If you are worried about people subclassing your class in general, the only real option you do have would be to seal your class:
public sealed class MyClass
{
This will prevent people from creating a subclass entirely. If you want to allow people to derive from your class, however, there is no way to prevent them from hiding your method in their class.
You can't prevent a public method or property being masked, but why would you? It takes a deliberate action from whoever extends the base class to do this (i.e. they need to type new), so they have intended to do it, why try and stop them?
Maybe you need to switch your pattern up a bit? If the extender must use your base method then you can put something critical in it, thus forcing them to call it. Of course this is smelly if not done correctly, so if you use this approach then mark your method as virtual, then in the documentation (or method header comments) mention that the base method must be called. This way you avoid the extender having to hide/mask your method (although they still could), but they can still extend it if they want.
I'm assuming you really want to prevent someone from overriding the method - hiding a method with new cannot be prevented, but it poses no risk to the base class, so that shouldn't be an issue.
In C# methods are not overrideable by default. So you can simply prevent someone form overriding a base method by not marking it virtual or abstract. In Java methods are virtual by default, so sealing a method by using final is necessary to prevent overriding.
I think the only way is to create interface the put your method definition within it, then let the original class to implement the interface and implement the method explicitly:
interface IAnimal
{
string diary(string notes, int sleephours);
}
class Dogs:IAnimal
{
virtual public string voice()
{
string v = "Hao Hao"; return v;
}
string IAnimal.diary(string notes,int sleephours)
{
return notes + sleep.ToString() + " hours";
}
}
class Cats:Dogs
{
public override string voice()
{
string v = "Miao Miao"; return v;
}
}
You will not use diary() method via Cats instance.
For prevent of hiding base class method you can do like this:
public class Org
{
public void Do()
{
// do something
}
}
public class Fake : Org
{
public new void Do()
{
base.Do();
// do something
}
}
here the base keyword refers to Father class.
now you called method from Father class (here is Org) in child class and now this method doesnt hide anymore.

Why using "new" when hiding methods?

Why is it necessary to use the new keyword when a method shall be hidden?
I have two classes:
public class Parent
{
public void Print()
{
Console.WriteLine("Parent");
}
}
public class Child : Parent
{
public void Print()
{
Console.WriteLine("Child");
}
}
Following code produces the given output:
Parent sut = new Child();
sut.Print();
Output: Parent
Child sut = new Child();
sut.Print();
Output: Child
I understand that this might be a problem if it the hiding was not intended but is there any other reason to use "new" (excepted avoding of warnings)?
Edit:
May be I was not clear. It is the same situation like:
public void foo(Parent p)
{
p.Print();
}
which is called:
Child c = new Child;
foo (c);c
No, but avoiding the warnings is incredibly important. The bugs caused by hiding can be insiduous, and after C++ (which just let you do it) both Java and C# chose two different ways to prevent them.
In Java, it is not possible to hide a base classes methods. The compiler will scream bloody murder if you try to do it.
In C#, there is the "new" keyword. It allows you to be explicit that you want to hide a method, and the compiler will warn you if you are not using it. Many developers make it a rule to have code compiler with no warnings because warnings can be a sign of bad code.
After all that, I have never had to use hiding. I would carefully consider why I was even considering using it, since its behavior is strange and almost never what I want.
If you are trying to use inheritance, you should make the method virtual in the base class, and override it in the child class.
The language designers have decided that when these keywords are not used, then method hiding should be explicitly done with the new keyword.
Hiding is a bad idea. It makes code more confusing, and your intent is unclear. Programming languages are about expressing your intent to both the compiler and to other programmers. It is not clear without a new keyword whether your intent was to override or to hide, or if you were just ignorant of the base method.
There's also an element of foolproofing. "Shoot-self in foot. Are you sure? OK/Cancel".
The real question is why is hiding allowed in the first place. The problem with not allowing hiding, is that if you derive from a class in another assembly and add a Foo() method, and then that other assembly is updated to add a Foo() method, not allowing for hiding would break your code.
Expanding on what Jon Hanna said...
The point of the warning is to tell you there is a name clash you might not be aware of. When you get the warning, you should do one of the following:
Add virtual and override to polymorphically override the method from the base class
Rename your method so its name no longer clashes with the method in the base class
Add new to make clear your intention to hide the method
If you are extending or refining the behaviour of the method in the base class, use virtual and override, as others have said here.
If you have just written your method for the first time and discover you have a name clash you weren't aware of and it is not your intention to override, simply rename your method.
Option 1 or 2 is usually preferable. So when should you resort to option 3?
You use option 3 when the base class is not your code. You don't have the option to add a virtual to it. The typical scenario where you need the new goes like this:
You bought a third party library. It has an interesting class. You inherit from the class and add a new method that the original author didn't provide. So far, there's no hiding or overriding involved. Now you receive a version 2 of the library, with some new features you want to use. The authors have added a new method to their class, and its name clashes with a method you wrote in your derived class.
If your method is not used very much, you should rename it out of the way, option 2. But if there are many dependencies on your method, it would be very disruptive to rename it. So you add the new to say that there is no logical connection between your method and the one in the base class, even though they happen to have the same name. You don't have the ability to add a virtual to the method in the base class, nor do you want to do that. The two methods were designed by different developers and your method doesn't refine or extend the one in the base class - when you wrote yours, the one in the base class didn't exist.
So, it's rare that you need the new keyword, but when you do, it's important.
Because it makes it explicit that you are deliberately hiding the parent's method, rather than overriding it. There is a warning when you don't use new because your subclass's method may have a typo in it, and accidentally hiding a parent method can lead to some subtle bugs.
You will have to use the new keyword if the method with the same signature in the base class isn't marked with abstract or virtual.
Just mark the Parent's method virtual. Then you would do public override void Print() in your child class.
public class Parent
{
public virtual void Print()
{
Console.WriteLine("Parent");
}
}
public class Child : Parent
{
public override void Print()
{
Console.WriteLine("Child");
}
}
This way you get the real inheritance and you can call the parents Print() method from the Child by calling base.Print()
Why is it necessary to use the new keyword when a method shall be hidden?
It is not necessary. The only function of new here is to suppress the warning.
The question could be: Why is it not an error to hide base class members?
The answer to the addition to your question
May be I was not clear. It is the same
situation like:
public void foo(Parent p) {
p.Print(); } which is called:
Child c = new Child; foo (c);
The answer is the foo(c) will output Parent. The method that hides the parent method will not execute if you are calling the parent class as in the example. To get the output of Child you will need to use virtual and override as described in earlier answers.
You can check the details here why method hiding allowed and to the scope of it.
https://msdn.microsoft.com/en-us/library/aa691135(v=vs.71).aspx

Categories

Resources