This question already has answers here:
Difference between new and override
(14 answers)
Closed 9 years ago.
Please find the code below:
using System;
namespace MainNS
{
abstract class BaseClass
{
abstract public void fun();
}
class DerivedClass1 : BaseClass
{
override public void fun()
{
Console.WriteLine("fun() of DerivedClass1 invoked!");
}
}
class DerivedClass2 : DerivedClass1
{
new public void fun()
{
Console.WriteLine("fun() of DerivedClass2 invoked!");
}
}
class MainClass
{
public static void Main(string[] args)
{
DerivedClass1 d1 = new DerivedClass2();
d1.fun();
Console.ReadKey();
}
}
}
What is the use of replacing new with override here and Please explain the actual concept behind this.
Override keyword makes fun() of DerivedClass2 to be executed and new keyword makes fun() of DerivedClass1 to be executed.
class DerivedClass2 : DerivedClass1
{
new public void fun()
{
Console.WriteLine("fun() of DerivedClass2 invoked!");
}
}
The following page summarizes your question very nicely.
Knowing When to Use Override and New Keywords
Summary
Override: When a method of a base class is overridden in a derived class, the version in the derived class is used, even if the calling code didn't "know" that the object was an instance of the derived class.
New: If you use the new keyword instead of override, the method in the derived class doesn't override the method in the base class, it merely hides it.
If you don't specify either new or overrides, the resulting output is the same as if you specified new, but you'll also get a compiler warning (as you may not be aware that you're hiding a method in the base class method, or indeed you may have wanted to override it, and merely forgot to include the keyword).
Override: used with virtual/abstract/override type of method in base class
New: when base class has not declared method as virtual/abstract/override
New Vs Override
Related
This question already has answers here:
new keyword in method signature
(9 answers)
Closed 9 years ago.
I have two classes
class A
{
public virtual void Metod1()
{
Console.WriteLine("A.Method1");
}
}
class B : A
{
public new void Metod1()
{
Console.WriteLine("B.Method1");
}
}
Then I write some code that declares instances of these classes, and calls their methods
static void Main(string[] args)
{
A a = new B();
a.Metod1();
B b = new B();
b.Metod1();
Console.ReadKey();
}
I gave following result:
A.Method1
B.Method1
But when I delete keyword new from signature method1 of class B and run Main method I got same result.
Question:Is new keyword in signature of methods only for better readability?
Edit:Are there cases where we can not do without a new keyword?
The new keyword let the code reader be aware that this method will hide the method with the same name in its base. Even if you ommited it, the compiler would treat it in the same way, but warn you about that.
Since you declared the method as virtual, you would get this warning when you compile:
'B.Metod1()' hides inherited member 'A.Metod1()'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword.
However, if you change the declaration by removing virtual as:
Declaration without virtual in A
class A {
public void Metod1() {
Console.WriteLine("A.Method1");
}
}
class B: A {
public void Metod1() {
Console.WriteLine("B.Method1");
}
}
Will still compile, but the warning message would be:
'B.Metod1()' hides inherited member 'A.Metod1()'. Use the new keyword if hiding was intended.
In either way as above, the following:
Test code
var b=new B();
b.Metod1();
(b as A).Metod1();
will output:
B.Method1
A.Method1
But, if you declare as the following:
Declaration with override in B
class A {
public virtual void Metod1() {
Console.WriteLine("A.Method1");
}
}
class B: A {
public override void Metod1() {
Console.WriteLine("B.Method1");
}
}
Then the output would be:
B.Method1
B.Method1
That is because Method1 of the base class is not just hidden but overridden by the derived class.
A case that you cannot just use new is that if Method1 is a abstract method in a abstract class:
Code that must use override in derived classes
abstract class A {
public abstract void Metod1();
}
class B: A {
public override void Metod1() { // use `new` instead of `override` would not compile
Console.WriteLine("B.Method1");
}
}
In this case you cannot just use new, because A requires derived classes to override Method1.
Knowing When to Use Override and New Keywords (C# Programming Guide)
In C#, a method in a derived class can have the same name as a method
in the base class. You can specify how the methods interact by using
the new and override keywords. The override modifier extends the base
class method, and the new modifier hides it.
also
By using new, you are asserting that you are aware that the member
that it modifies hides a member that is inherited from the base
class.
Yes, you are correct, it is for better readability in this situation.
But check carefully you should have a warning for not using new when hiding the base method.
You can read more here:
http://msdn.microsoft.com/en-us/library/vstudio/435f1dw2.aspx
I'm trying to refresh my memory but can't find answers with Google.
public class BaseClass
{
public virtual void DoSomething()
{
Trace.Write("base class");
}
}
public class DerivedClass : BaseClass
{
public override void DoSomething()
{
Trace.Write("derived class");
}
}
If I create an instance of derived class, how do I convert it to it's base class so that when DoSomething() is called, it uses the base class's method only?
A dynamic cast still calls the derived class's overridden method:
DerivedClass dc = new DerivedClass();
dc.DoSomething();
(dc as BaseClass).DoSomething();
Output: "derived class"
Although this sounds irrational but it works
DerivedClass B = new DerivedClass();
BaseClass bc = JsonConvert.DeserializeObject<BaseClass>(JsonConvert.SerializeObject(B));
You can't - that's entirely deliberate, as that's what polymorphism is all about. Suppose you have a derived class which enforces certain preconditions on the arguments you pass to an overridden method, in order to maintain integrity... you don't want to be able to bypass that validation and corrupt its internal integrity.
Within the class itself you can non-virtually call base.AnyMethod() (whether that's the method you're overriding or not) but that's okay because that's the class itself deciding to potentially allow its integrity to be violated - presumably it knows what it's doing.
You absolutely CAN (call the base method), just read up on Polymorphism:
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/polymorphism
Example:
public class BaseClass
{
public void DoWork() { }
public int WorkField;
public int WorkProperty
{
get { return 0; }
}
}
public class DerivedClass : BaseClass
{
public new void DoWork() { }
public new int WorkField;
public new int WorkProperty
{
get { return 0; }
}
}
And how to call it:
DerivedClass B = new DerivedClass();
B.DoWork(); // This calls the new method.
BaseClass A = (BaseClass)B;
A.DoWork(); // This calls the old method.
Try using the new keywor instead of override As far as i know this should enable that desired behavior.
I'm not realy sure about that so please don't blame me if i'm wrong!
public class BaseClass
{
public virtual void DoSomething()
{
Trace.Write("base class");
}
}
public class DerivedClass : BaseClass
{
public new void DoSomething()
{
Trace.Write("derived class");
}
}
The solutions with new instead of override break the polymorphism. Recently I came to the same problem and implemented it the following way. My solution has the following advantages:
virtual and override stays in place;
name BaseClass is not used directly in the type cast, so if I introduce an intermediate MiddleClass in the hierarchy between BaseClass and DerivedClass, which also implements DoSomething(); then the MiddleClass's implementation won't be skipped.
This is the implementation:
public class BaseClass
{
public virtual void DoSomething()
{
Trace.Write("base class");
}
}
public class DerivedClass : BaseClass
{
public override void DoSomething()
{
Trace.Write("derived class");
}
public void BaseDoSomething()
{
base.DoSomething();
}
}
The usage is:
DerivedClass dc = new DerivedClass();
dc.DoSomething();
dc.BaseDoSomething();
For VB.net, I've used the following code to do the conversion (shown with Lists of Objects):
Dim tempPartialList As New List(Of clsBaseData)
For Each iterClsDerivedData As clsDerivedData In ListOfDerivedDataObjects
tempPartialList.Add(CType(iterClsDerivedData, clsBaseData))
Next
Where clsBaseData is the Base Class from which clsDerivedData is made by Inheriting clsBaseData.
ListOfDerivedDataObjects is a List(Of clsDerivedData).
I have found this useful where I have Lists of several Derived Classes and I would like to operate on a property of the Base Class for all the objects in the Lists of Derived Classes. The tempPartialList is, for me, a temporary List meant to facilitate changing this property.
I just could not find a satisfactory explanation for this. So I thought it would help to post this at SO.
What happens when we combine method hiding and overriding in C# ?
For the below example :
class BaseClassA
{
public virtual void showMessage()
{
Console.WriteLine("In BaseClass A ");
}
}
class DerivedClassB : BaseClassA
{
public override void showMessage()
{
Console.WriteLine("In DerivedClass B ");
}
}
class DerivedClassC : DerivedClassB
{
public new void showMessage()
{
Console.WriteLine("In DerivedClass C");
}
}
class Program
{
static void Main(string[] args)
{
BaseClassA a = new BaseClassA();
a.showMessage();
a = new DerivedClassB();
a.showMessage();
BaseClassA b = new DerivedClassC();
b.showMessage();
Console.ReadKey();
}
}
I am understanding the output of
BaseClassA b = new DerivedClassC();
b.showMessage();
Here's what I understand for new and override in C#
New - It hides the baseclass method. So even if baseclass reference variable points to a derived class object if that derived class hides the method, the output will be baseclass output only.
Override - It overrides the baseclass method. So even if baseclass reference variable points to a derived class object if that derived class overrides the method, the output will be derived class output.
But here how can even a BaseClassA reference variable point to a DerivedClassC object and print DerivedClassB's output ?
Please explain in simple words.
But here how can even a BaseClassA reference variable point to DerivedClassC object and it prints DerivedClassB's output ?
The code calls the method which is declared by BaseClassA but overridden by DerivedClassB. The method declared in DerivedClassC is a new method, entirely separate from the one declared in BaseClassA... as if it had a different name, in a way.
Effectively, think of it this way:
If DerivedClassC didn't declare a showMessage method at all, it would inherit the implementation from DerivedClassB, right?
Introducing a new method doesn't change the output because it's a separate method which isn't involved in overriding the method introduced in DerivedClassA. So the output is the same as with the previous step.
I think that trying DerivedClassC as just
class DerivedClassC : DerivedClassB
{
}
and understanding that output is the key to understanding the later behaviour.
This question already has answers here:
new keyword in method signature
(9 answers)
Closed 9 years ago.
I have two classes
class A
{
public virtual void Metod1()
{
Console.WriteLine("A.Method1");
}
}
class B : A
{
public new void Metod1()
{
Console.WriteLine("B.Method1");
}
}
Then I write some code that declares instances of these classes, and calls their methods
static void Main(string[] args)
{
A a = new B();
a.Metod1();
B b = new B();
b.Metod1();
Console.ReadKey();
}
I gave following result:
A.Method1
B.Method1
But when I delete keyword new from signature method1 of class B and run Main method I got same result.
Question:Is new keyword in signature of methods only for better readability?
Edit:Are there cases where we can not do without a new keyword?
The new keyword let the code reader be aware that this method will hide the method with the same name in its base. Even if you ommited it, the compiler would treat it in the same way, but warn you about that.
Since you declared the method as virtual, you would get this warning when you compile:
'B.Metod1()' hides inherited member 'A.Metod1()'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword.
However, if you change the declaration by removing virtual as:
Declaration without virtual in A
class A {
public void Metod1() {
Console.WriteLine("A.Method1");
}
}
class B: A {
public void Metod1() {
Console.WriteLine("B.Method1");
}
}
Will still compile, but the warning message would be:
'B.Metod1()' hides inherited member 'A.Metod1()'. Use the new keyword if hiding was intended.
In either way as above, the following:
Test code
var b=new B();
b.Metod1();
(b as A).Metod1();
will output:
B.Method1
A.Method1
But, if you declare as the following:
Declaration with override in B
class A {
public virtual void Metod1() {
Console.WriteLine("A.Method1");
}
}
class B: A {
public override void Metod1() {
Console.WriteLine("B.Method1");
}
}
Then the output would be:
B.Method1
B.Method1
That is because Method1 of the base class is not just hidden but overridden by the derived class.
A case that you cannot just use new is that if Method1 is a abstract method in a abstract class:
Code that must use override in derived classes
abstract class A {
public abstract void Metod1();
}
class B: A {
public override void Metod1() { // use `new` instead of `override` would not compile
Console.WriteLine("B.Method1");
}
}
In this case you cannot just use new, because A requires derived classes to override Method1.
Knowing When to Use Override and New Keywords (C# Programming Guide)
In C#, a method in a derived class can have the same name as a method
in the base class. You can specify how the methods interact by using
the new and override keywords. The override modifier extends the base
class method, and the new modifier hides it.
also
By using new, you are asserting that you are aware that the member
that it modifies hides a member that is inherited from the base
class.
Yes, you are correct, it is for better readability in this situation.
But check carefully you should have a warning for not using new when hiding the base method.
You can read more here:
http://msdn.microsoft.com/en-us/library/vstudio/435f1dw2.aspx
How do I prevent a method from being overridden in a derived class?
In Java I could do this by using the final modifier on the method I wish to prevent from being overridden.
How do I achieve the same in C#?
I am aware of using sealed but apparently I can use it only with the override keyword?
class A
{
public void methodA()
{
// Code.
}
public virtual void methodB()
{
// Code.
}
}
class B : A
{
sealed override public void methodB()
{
// Code.
}
}
So in the above example I can prevent the methodB() from being overridden by any classes deriving from class B, but how do I prevent class B from overriding the methodB() in the first place?
Update: I missed the virtual keyword in the methodB() declaration on class A when i posted this question. Corrected it.
You don't need to do anything. The virtual modifier specifies that a method can be overridden. Omitting it means that the method is 'final'.
Specifically, a method must be virtual, abstract, or override for it to be overridden.
Using the new keyword will allow the base class method to be hidden, but it will still not override it i.e. when you call A.methodB() you will get the base class version, but if you call B.methodB() you will get the new version.
As you mentioned, you can prevent further overriding of MethodB in class B by using sealed with override
class B : A
{
public sealed override void methodB()
{
Console.WriteLine("Class C cannot override this method now");
}
}
Use of the sealed modifier along with override prevents a derived class from further overriding the method.
If you do not want methodB in class A to be overridden by any child classes, do not mark that method virtual. Simply remove it. virtual keyword enable the method to be overridden in child classes
public void methodA()
{
}
Use sealed keyword on your classes to prevent further overriding of the class
In C#, a function not marked virtual (which also includes overrides of virtual functions) is effectively sealed and cannot be overridden. So, your example code actually won't compile because the override keyword is not valid unless there is a method marked virtual with the same signature in a base class.
If A.methodB() were marked virtual, then you could override the method from A, but prevent it being further overridden in classes deriving more indirectly, using the sealed keyword exactly as you have shown.
One thing to keep in mind is that while method overriding can be prevented, method hiding cannot. Given your current definition of class A, the following definition of class B is legal and there's nothing you can do about it:
class B:A
{
public new void methodB()
{
//code
}
}
The new keyword basically "breaks" the inheritance/overriding hierarchy as it pertains to this one method; any reference to a class B, treated as a class B (or any further derived type) will use the implementation from class B and ignore the one from class A unless B's implementation specifically calls back to it. However, if you were to treat an instance of class B as a class A (by casting it or passing it as a parameter), then the "new" implementation is ignored.
This differs from overriding, where a class B that is being treated as a class A and truly overrides a virtual methodB would still use class B's override of the method. Also understand that method hiding is inferred (though you will get a compiler warning); if you declare a method with the same signature in a derived class and do not specify either new or override, the base class method will be hidden.
In a base class, the sealed keyword is only used to prevent a class from being derived, but in inherited classes it can be used to prevent another inherited class from overriding the method.
To prevent a base class method from being overridden, just do not specify it as virtual. In the example you provided, class B could not override methodB because methodB was not marked as virtual on the original class.
this will compile:
class A
{
public virtual void methodA()
{
//code
}
public virtual void methodB()
{
//code
}
}
class B:A
{
public override void methodB()
{
//code
}
}
this will not:
class A
{
public void methodA()
{
//code
}
public void methodB()
{
//code
}
}
class B:A
{
public override void methodB()
{
//code
}
}
EDITTED: clarified and corrected my original statement about the sealed keyword