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
Related
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.
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.
Say I have an abstract parent class called "Parent" that implements a method called "DisplayTitle". I want this method to be the same for each subclass that inherits "Parent" - I would like a compile error if a subclass attempts to implement their own "DisplayTitle" method. How can I accomplish this in C#. I believe in Java, I'd just mark the method as "final", but I can't seem to find an alternative in C#. I've been messing around with "sealed" and "override", but I can't get the behavior that I'm looking for.
For example, in this code:
using System;
namespace ConsoleApplication1
{
class Parent
{
public void DisplayTitle() { Console.WriteLine("Parent's Title"); }
}
class ChildSubclass : Parent
{
public void DisplayTitle() { Console.WriteLine("Child's Own Implementation of Title");
}
static void Main(string[] args)
{
ChildSubclass myChild = new ChildSubclass();
myChild.DisplayTitle();
Console.ReadLine();
}
}
}
I'd like to receive a compile error saying that the "ChildSubClass" can't override "DisplayTitle". I currently get a warning - but it seems like this is something that I should be able to do and I don't know the proper attributes to label the method.
How can I accomplish this in C#. I believe in Java, I'd just mark the method as "final", but I can't seem to find an alternative in C#.
The rough equivalent is sealed in C#, but you normally only need it for virtual methods - and your DisplayTitle method isn't virtual.
It's important to note that ChildSubclass isn't overriding DisplayTitle - it's hiding it. Any code which only uses references to Parent won't end up calling that implementation.
Note that with the code as-is, you should get a compile-time warning advising you to add the new modifier to the method in ChildSubclass:
public new void DisplayTitle() { ... }
You can't stop derived classes from hiding existing methods, other than by sealing the class itself to prevent the creation of a derived class entirely... but callers which don't use the derived type directly won't care.
What's your real concern here? Accidental misuse, or deliberate problems?
EDIT: Note that the warning for your sample code would be something like:
Test.cs(12,19): warning CS0108:
'ConsoleApplication1.ChildSubclass.DisplayTitle()' hides inherited
member 'ConsoleApplication1.Parent.DisplayTitle()'. Use the new keyword
if hiding was intended.
I suggest you turn warnings into errors, and then it's harder to ignore them :)
A derived class cannot override your method, you didn't declare it virtual. Note how that's very different in C# compared to Java, all methods are virtual in Java. In C# you must explicitly use the keyword.
A derived class can hide your method by using the same name again. This is probably the compile warning you are talking about. Using the new keyword suppresses the warning. This method does not in any way override your original method, your base class code always calls the original method, not the one in the derived class.
Use the sealed modifier to prevent subclasses from overriding your classes, properties, or methods. What isn't working when you use sealed?
http://msdn.microsoft.com/en-us/library/88c54tsw.aspx
I'm fairly certain that what you want is not possible in C# using method modifier keywords.
Sealed only applies when overriding a virtual method in an ancestor class, which then prevent further overriding.
This is more or less an exact duplicate of this post, but as I cannot edit it, I started this. Feel free to move something over and close this one.
Using method hiding with new seems like a dangerous feature, and given the discussion in the other thread, it seems it's not only I who have problems finding a valid use case for this. Any methods accepting Base won't use Derived's Method.
public class Base
{
public void Method()
{
Console.WriteLine("Base");
}
}
public class Derived : Base
{
public new void Method()
{
Console.WriteLine("Derived");
}
}
var derived = new Derived();
derived.Method(); // "Derived"
((Base)derived).Method(); // "Base"
So what are some valid use cases for new that is difficult to solve with other features?
The idea is to avoid the brittle base class problem as far as possible.
Suppose you provide a library, and I derive from one of your classes. I create my own method, Foo(), and call it appropriately. Fine.
Now you introduce a second version of your library, and you add the Foo() method (with the same signature) to the base class. Now your code will call Foo(), which has one particular meaning... and that may be a completely different meaning to my Foo() method. The default behaviour (and the behaviour if you add the new modifier) is for things to behave as they should: code which only knows about the base class will call your method - which is fine, as that's what they mean. Code which uses an expression which has a compile-time type of my derived class will use my method - and that's fine, as that's what they should mean as well. (Basically it can only be my code, because only my code knows about my class.)
It should usually be avoided - it can lead to subtle bugs where changing the compile-time type of the variable silently changes the behaviour... but it's present for that sort of situation. Basically, adding a method to a base class shouldn't break derived classes, as far as possible.
I've found loads of practical examples of this, and understand the practical output when overriding or hiding methods, but I'm looking for some under the covers info on why this is and why C# allows it when according to the rules of polymorphism, this shouldn't be allowed - at least, insofar as my understanding of polymorphism goes (which seems to coincide with the standard definitions found on Wikipedia/Webopedia).
Class Base
{
public virtual void PrintName()
{
Console.WriteLine("BaseClass");
}
}
Class FirstDerived : Base
{
public override void PrintName()
{
Console.WriteLine("FirstDerived");
}
}
Class SecondDerived : Base
{
public new void PrintName()
{
Console.WriteLine("SecondDerived");
}
}
Using the following code:
FirstDerived b = new FirstDerived();
BaseClass a = b;
b.PrintName();
a.PrintName();
I get:
FirstDerived
FirstDerived
Okay, I get that, makes sense.
SecondDerived c = new SecondDerived();
BaseClass a = c;
c.PrintName();
a.PrintName();
I get:
SecondDerived
BaseClass
Okay, that makes sense, too, instance a can't see c.PrintName() so it's using its own method to print its own name, however I can cast my instance to its true type using:
((SecondDerived)a).PrintName();
or
(a as SecondDerived).PrintName();
to get the output I would expect:
SecondDerived
So what is going on under the covers and what does this mean in terms of polymorphism? I'm told that this facility "breaks polymorphism" - and I guess according to the definition, it does. Is that right? Would an "object oriented" langage like C# really allow you to break one of the core principles of OOP?
(This answers the "why is it allowed" which I think is really the central point of your question. How it works in terms of the IL is less interesting to my mind... let me know if you want me to go into that though. Basically it's just a case of specifying the method to call with a different type token.)
It allows base classes to evolve without breaking derived classes.
Suppose Base didn't originally have the PrintName method. The only way to get at SecondDerived.PrintName would be to have an expression with a static type of SecondDerived, and call it on that. You ship your product, everything is fine.
Now fast forward to Base introducing a PrintName method. This may or may not have the same semantics of SecondDerived.PrintName - it's safest to assume that it doesn't.
Any callers of Base.PrintName know that they're calling the new method - they couldn't have called it before. Any callers which were previously using SecondDerived.PrintName still want to use it though - they don't want to suddenly end up calling Base.PrintName which could do something entirely different.
The difficulty is new callers of SecondDerived.PrintName, who may or may not appreciate that this isn't an override of Base.PrintName. They may be able to notice this from the documentation of course, but it may not be obvious. However, at least we haven't broken existing code.
When SecondDerived is recompiled though, the authors will be made aware that there's now a Base.PrintName class through a warning. They can either stick to their existing non-virtual scheme by adding the new modifier, or make it override the Base.PrintName method. Until they make that decision, they'll keep getting a warning.
Versioning and compatibility isn't usually mentioned in OO theory in my experience, but C# has been designed to try to avoid compatibility nightmares. It doesn't solve the problem completely, but it does a pretty good job.
I answer "how" it works. Jon has answered the "Why" part.
Calls to virtual methods are resolved a bit differently to those of non-virtual ones. Basically, a virtual method declaration introduces a "virtual method slot" in the base class. The slot will hold a pointer to the actual method definition (and the contents will point to an overridden version in the derived classes and no new slot will be created). When the compiler generates code for a virtual method call, it uses the callvirt IL instruction, specifying the method slot to call. The runtime will dispatch the call to the appropriate method. On the other hand, a non-virtual method is called with a call IL instruction, which will be statically resolved to the actual method by the compiler, at compile time (only with the knowledge of the compile-time type of the variable). new modifier does nothing in the compiled code. It essentially tells the C# compiler "Dude, shut up! I'm sure I'm doing the right thing" and turns off the compiler warning.
A new method (actually, any method without an override modifier) will introduce a completely separate chain of methods (new method slot). Note that a new method can be virtual itself. The compiler will look at the static type of the variable when it wants to resolve the method chain and the run time will choose the actual method in that specific chain.
According to the Wikipedia definition:
Type polymorphism in object-oriented
programming is the ability of one
type, A, to appear as and be used like
another type, B
Later on the same page:
Method overriding is where a subclass
replaces the implementation of one or
more of its parent's methods. Neither
method overloading nor method
overriding are by themselves
implementations of polymorphism.
The fact that SecondDerived does not provide an override for the PrintName does not affect its ability to appear and be used as Base. The new method implementation it provides will not be used anywhere an instance of SecondDerived is treated as an instance of the Base; it will be used only when that instance is explicitly used as an instance of SecondDerived.
Moreover, SecondClass can actually explicitly implement the Base.PrintName in addition to the new hiding implementation, thus providing its own override that will be used when treated as Base. (Though, Base has to be an explicit interface definition or has to derive from one to allow this)