In "The C# Programming Language" book Eric Lippert mentioned this:
A subtle point here is that an overridden virtual method is still considered to be a method of the class that introduced it, and not a method of the class that overrides it.
What is the significance of this statement? Why does it matter if the overridden virtual method is considered to be a method of the class that introduced it (or otherwise) since the overridden method will never be called unless you are dealing with the derived class?
It matters when you have a reference of one type pointing to an object of a different type.
Example:
public class BaseClass {
public virtual int SomeVirtualMethod() { return 1; }
}
public class DerivedClass : BaseClass {
public override int SomeVirtualMethod() { return 2; }
}
BaseClass ref = new DerivedClass();
int test = ref.SomeVirtualMethod(); // will be 2
Because the virtual method is a member of the base class, you can call the overriding method with a reference of the base class type. If it wasn't, you would need a reference of the derived type to call the overriding method.
When you are shadowing a method instead of overriding it, the shadowing method is a member of the derived class. Depending on the type of the reference you will be calling the original method or the shadowing method:
public class BaseClass {
public int SomeMethod() { return 1; }
}
public class DerivedClass : BaseClass {
public new int SomeMethod() { return 2; }
}
BaseClass ref = new DerivedClass();
int test = ref.SomeMethod(); // will be 1
DerivedClass ref2 = ref;
int test2 = ref2.SomeMethod(); // will be 2
Here's the full quote from the book:
A subtle point here is that an overridden virtual method is still considered to be a method of the class that introduced it, and not a method of the class that overrides it. The overload resolution rules in some cases prefer members of more derived types to those in base types; overriding a method does not "move" where that method belongs in this hierarchy.
At the very beginning of this section, we noted that C# was designed with versioning in mind. This is one of those features that helps prevent "brittle base-class syndrome" from causing versioning problems.
The full quote makes it clear that Eric Lippert is talking specifically about method overloading, not just about how virtual methods work.
As an example, consider the following program:
class Base
{
public virtual void M2(int i) { }
}
class Derived : Base
{
public void M1(int i) { Console.WriteLine("Derived.M1(int)"); }
public void M1(float f) { Console.WriteLine("Derived.M1(float)"); }
public override void M2(int i) { Console.WriteLine("Derived.M2(int)"); }
public void M2(float f) { Console.WriteLine("Derived.M2(float)"); }
public static void Main()
{
Derived d = new Derived();
d.M1(1);
d.M2(1);
}
}
I think many developers would be surprised that the output is
Derived.M1(int)
Derived.M2(float)
Why would d.M2(1) invoke Derived.M2(float) even though Derived.M2(int) is a better match?
When the compiler is determining what the M1 in d.M1(1) refers to, the compiler sees that both M1(int) and M1(float) are introduced in Derived, so both overloads are applicable candidates. The compiler selects M1(int) over M1(float) as the best match for the integer argument 1.
When the compiler is determining what the M2 in d.M2(1) refers to, the compiler sees that M2(float) is introduced in Derived and is an applicable candidate. According to the overload resolution rules, "methods in a base class are not candidates if any method in a derived class is applicable". Because M2(float) is applicable, this rule prevents M2(int) from being a candidate. Even though M2(int) is a better match for the integer argument and even though it's overridden in Derived, it's still considered to be a method of Base.
Understanding that an overridden virtual method belongs to the class which introduces it, rather than the class that overrides it, makes it easier to understand the way class members are bound. Except when using dynamic objects, all bindings in C# are resolved at compile time. If a BaseClass declares a virtual method foo, and DerivedClass:BaseClass overrides foo, code which attempts to call foo on a variable of type BaseClass will always be bound to virtual method "slot" BaseClass.foo, which will in turn point to the actual DerivedClass.foo method.
This understanding can be especially important when dealing with generics, since in C#, unlike C++, members of generic types are bound according to the generics' constraints, rather than according to the concrete generic types. For example, suppose there were a SubDerivedClass:DerivedClass which created a new virtual method foo(), and one defined a method DoFoo<T>(T param) where T:BaseClass {param.foo();}. The param.foo() call would be bound to BaseClass.foo even if the method were invoked as DoFoo<SubDrivedClass>(subDerivedInstance). If the parameter were cast to SubDerivedClass before invoking foo, the call would be bound to SubDrivedClass.foo(), but the compiler can't tell when producing DoFoo<T> that T will be anything more specific than BaseClass, it can't bind to anything that doesn't exist in BaseClass.
Incidentally, there are times it would be useful if a class could simultaneously override a base-class member and create a new one; for example, given an abstract base class ReadableFoo with some abstract read-only property, it would be helpful if a class MutableFoo could both provide an override for that property and define a read-write property with the same name. Unfortunately, .net does not allow that. Given such a restriction, the best approach may be for ReadableFoo to provide a concrete non-virtual read-only property which calls an protected abstract method with a different name to get the value. That way, a derived class could shadow the read-only property with a read-write one (that would call the same virtual method for reading, or a new (possibly virtual) method for writing.
(following is untested)
class BaseClass
{
public virtual void foo() {Console.WriteLine("BaseClass.Foo");
}
class DerivedClass:BaseClass
{
public override void foo() {Console.WriteLine("Derived.Foo");
}
class SubDerivedClass:DerivedClass
{
public new virtual void foo() {Console.WriteLine("SubDerived.Foo");
}
class MegaDerivedClass:SubDerivedClass
{
public override void foo() {Console.WriteLine("MegaDerived.Foo");
}
void DoFoo1<T>(T param) where T:BaseClass
{
param.foo();
}
void DoFoo1<T>(T param) where T:SubDerivedClass
{
param.foo();
}
void test(void)
{
var megaDerivedInstance = new MegaDerivedClass();
DoFoo1<MegaDerivedClass>(megaDerivedInstance);
DoFoo2<MegaDerivedClass>(megaDerivedInstance);
}
A SubDerivedClass has two virtual foo() methods: BaseClass.foo() and SubDerivedClass.foo(). A MegaDerivedClass has those same two methods. Note that classes derived from SubDerivedClass() which attempt to override foo will override SubDerivedClass.foo() and will not affect BaseClass.foo(); with the declarations as above, no derivative of SubDerivedClass can override BaseClass.Foo. Note also that casting an instance of SubDerivedClass or a subclass thereof to DerivedClass or BaseClass will expose the BaseClass.foo virtual method for calling.
Incidentally, if the method declaration in SubDerivedClass had been friend new virtual void foo() {Console.WriteLine("SubDerived.Foo");, it would be impossible for other classes within the same assembly to override BaseClass.foo() (since any attempt to override foo() would override SubDerivedClass.foo()), but classes outside the assembly which derive from SubDerivedClass wouldn't see SubDerivedClass.foo() and could thus override BaseClass.foo().
Related
What are differences between declaring a method in a base type "virtual" and then overriding it in a child type using the "override" keyword as opposed to simply using the "new" keyword when declaring the matching method in the child type?
I always find things like this more easily understood with pictures:
Again, taking joseph daigle's code,
public class Foo
{
public /*virtual*/ bool DoSomething() { return false; }
}
public class Bar : Foo
{
public /*override or new*/ bool DoSomething() { return true; }
}
If you then call the code like this:
Foo a = new Bar();
a.DoSomething();
NOTE: The important thing is that our object is actually a Bar, but we are storing it in a variable of type Foo (this is similar to casting it)
Then the result will be as follows, depending on whether you used virtual/override or new when declaring your classes.
The "new" keyword doesn't override, it signifies a new method that has nothing to do with the base class method.
public class Foo
{
public bool DoSomething() { return false; }
}
public class Bar : Foo
{
public new bool DoSomething() { return true; }
}
public class Test
{
public static void Main ()
{
Foo test = new Bar ();
Console.WriteLine (test.DoSomething ());
}
}
This prints false, if you used override it would have printed true.
(Base code taken from Joseph Daigle)
So, if you are doing real polymorphism you SHOULD ALWAYS OVERRIDE. The only place where you need to use "new" is when the method is not related in any way to the base class version.
Here's some code to understand the difference in the behavior of virtual and non-virtual methods:
class A
{
public void foo()
{
Console.WriteLine("A::foo()");
}
public virtual void bar()
{
Console.WriteLine("A::bar()");
}
}
class B : A
{
public new void foo()
{
Console.WriteLine("B::foo()");
}
public override void bar()
{
Console.WriteLine("B::bar()");
}
}
class Program
{
static int Main(string[] args)
{
B b = new B();
A a = b;
a.foo(); // Prints A::foo
b.foo(); // Prints B::foo
a.bar(); // Prints B::bar
b.bar(); // Prints B::bar
return 0;
}
}
The new keyword actually creates a completely new member that only exists on that specific type.
For instance
public class Foo
{
public bool DoSomething() { return false; }
}
public class Bar : Foo
{
public new bool DoSomething() { return true; }
}
The method exists on both types. When you use reflection and get the members of type Bar, you will actually find 2 methods called DoSomething() that look exactly the same. By using new you effectively hide the implementation in the base class, so that when classes derive from Bar (in my example) the method call to base.DoSomething() goes to Bar and not Foo.
Beyond just the technical details, I think using virtual/override communicates a lot of semantic information on the design. When you declare a method virtual, you indicate that you expect that implementing classes may want to provide their own, non-default implementations. Omitting this in a base class, likewise, declares the expectation that the default method ought to suffice for all implementing classes. Similarly, one can use abstract declarations to force implementing classes to provide their own implementation. Again, I think this communicates a lot about how the programmer expects the code to be used. If I were writing both the base and implementing classes and found myself using new I'd seriously rethink the decision not to make the method virtual in the parent and declare my intent specifically.
virtual / override tells the compiler that the two methods are related and that in some circumstances when you would think you are calling the first (virtual) method it's actually correct to call the second (overridden) method instead. This is the foundation of polymorphism.
(new SubClass() as BaseClass).VirtualFoo()
Will call the SubClass's overriden VirtualFoo() method.
new tells the compiler that you are adding a method to a derived class with the same name as a method in the base class, but they have no relationship to each other.
(new SubClass() as BaseClass).NewBar()
Will call the BaseClass's NewBar() method, whereas:
(new SubClass()).NewBar()
Will call the SubClass's NewBar() method.
The difference between the override keyword and new keyword is that the former does method overriding and the later does method hiding.
Check out the folllowing links for more information...
MSDN and Other
new keyword is for Hiding. - means you are hiding your method at runtime. Output will be based base class method.
override for overriding. - means you are invoking your derived class method with the reference of base class. Output will be based on derived class method.
My version of explanation comes from using properties to help understand the differences.
override is simple enough, right ? The underlying type overrides the parent's.
new is perhaps the misleading (for me it was). With properties it's easier to understand:
public class Foo
{
public bool GetSomething => false;
}
public class Bar : Foo
{
public new bool GetSomething => true;
}
public static void Main(string[] args)
{
Foo foo = new Bar();
Console.WriteLine(foo.GetSomething);
Bar bar = new Bar();
Console.WriteLine(bar.GetSomething);
}
Using a debugger you can notice that Foo foo has 2 GetSomething properties, as it actually has 2 versions of the property, Foo's and Bar's, and to know which one to use, c# "picks" the property for the current type.
If you wanted to use the Bar's version, you would have used override or use Foo foo instead.
Bar bar has only 1, as it wants completely new behavior for GetSomething.
Not marking a method with anything means: Bind this method using the object's compile type, not runtime type (static binding).
Marking a method with virtual means: Bind this method using the object's runtime type, not compile time type (dynamic binding).
Marking a base class virtual method with override in derived class means: This is the method to be bound using the object's runtime type (dynamic binding).
Marking a base class virtual method with new in derived class means: This is a new method, that has no relation to the one with the same name in the base class and it should be bound using object's compile time type (static binding).
Not marking a base class virtual method in the derived class means: This method is marked as new (static binding).
Marking a method abstract means: This method is virtual, but I will not declare a body for it and its class is also abstract (dynamic binding).
using System;
using System.Text;
namespace OverrideAndNew
{
class Program
{
static void Main(string[] args)
{
BaseClass bc = new BaseClass();
DerivedClass dc = new DerivedClass();
BaseClass bcdc = new DerivedClass();
// The following two calls do what you would expect. They call
// the methods that are defined in BaseClass.
bc.Method1();
bc.Method2();
// Output:
// Base - Method1
// Base - Method2
// The following two calls do what you would expect. They call
// the methods that are defined in DerivedClass.
dc.Method1();
dc.Method2();
// Output:
// Derived - Method1
// Derived - Method2
// The following two calls produce different results, depending
// on whether override (Method1) or new (Method2) is used.
bcdc.Method1();
bcdc.Method2();
// Output:
// Derived - Method1
// Base - Method2
}
}
class BaseClass
{
public virtual void Method1()
{
Console.WriteLine("Base - Method1");
}
public virtual void Method2()
{
Console.WriteLine("Base - Method2");
}
}
class DerivedClass : BaseClass
{
public override void Method1()
{
Console.WriteLine("Derived - Method1");
}
public new void Method2()
{
Console.WriteLine("Derived - Method2");
}
}
}
What are differences between declaring a method in a base type "virtual" and then overriding it in a child type using the "override" keyword as opposed to simply using the "new" keyword when declaring the matching method in the child type?
I always find things like this more easily understood with pictures:
Again, taking joseph daigle's code,
public class Foo
{
public /*virtual*/ bool DoSomething() { return false; }
}
public class Bar : Foo
{
public /*override or new*/ bool DoSomething() { return true; }
}
If you then call the code like this:
Foo a = new Bar();
a.DoSomething();
NOTE: The important thing is that our object is actually a Bar, but we are storing it in a variable of type Foo (this is similar to casting it)
Then the result will be as follows, depending on whether you used virtual/override or new when declaring your classes.
The "new" keyword doesn't override, it signifies a new method that has nothing to do with the base class method.
public class Foo
{
public bool DoSomething() { return false; }
}
public class Bar : Foo
{
public new bool DoSomething() { return true; }
}
public class Test
{
public static void Main ()
{
Foo test = new Bar ();
Console.WriteLine (test.DoSomething ());
}
}
This prints false, if you used override it would have printed true.
(Base code taken from Joseph Daigle)
So, if you are doing real polymorphism you SHOULD ALWAYS OVERRIDE. The only place where you need to use "new" is when the method is not related in any way to the base class version.
Here's some code to understand the difference in the behavior of virtual and non-virtual methods:
class A
{
public void foo()
{
Console.WriteLine("A::foo()");
}
public virtual void bar()
{
Console.WriteLine("A::bar()");
}
}
class B : A
{
public new void foo()
{
Console.WriteLine("B::foo()");
}
public override void bar()
{
Console.WriteLine("B::bar()");
}
}
class Program
{
static int Main(string[] args)
{
B b = new B();
A a = b;
a.foo(); // Prints A::foo
b.foo(); // Prints B::foo
a.bar(); // Prints B::bar
b.bar(); // Prints B::bar
return 0;
}
}
The new keyword actually creates a completely new member that only exists on that specific type.
For instance
public class Foo
{
public bool DoSomething() { return false; }
}
public class Bar : Foo
{
public new bool DoSomething() { return true; }
}
The method exists on both types. When you use reflection and get the members of type Bar, you will actually find 2 methods called DoSomething() that look exactly the same. By using new you effectively hide the implementation in the base class, so that when classes derive from Bar (in my example) the method call to base.DoSomething() goes to Bar and not Foo.
Beyond just the technical details, I think using virtual/override communicates a lot of semantic information on the design. When you declare a method virtual, you indicate that you expect that implementing classes may want to provide their own, non-default implementations. Omitting this in a base class, likewise, declares the expectation that the default method ought to suffice for all implementing classes. Similarly, one can use abstract declarations to force implementing classes to provide their own implementation. Again, I think this communicates a lot about how the programmer expects the code to be used. If I were writing both the base and implementing classes and found myself using new I'd seriously rethink the decision not to make the method virtual in the parent and declare my intent specifically.
virtual / override tells the compiler that the two methods are related and that in some circumstances when you would think you are calling the first (virtual) method it's actually correct to call the second (overridden) method instead. This is the foundation of polymorphism.
(new SubClass() as BaseClass).VirtualFoo()
Will call the SubClass's overriden VirtualFoo() method.
new tells the compiler that you are adding a method to a derived class with the same name as a method in the base class, but they have no relationship to each other.
(new SubClass() as BaseClass).NewBar()
Will call the BaseClass's NewBar() method, whereas:
(new SubClass()).NewBar()
Will call the SubClass's NewBar() method.
The difference between the override keyword and new keyword is that the former does method overriding and the later does method hiding.
Check out the folllowing links for more information...
MSDN and Other
new keyword is for Hiding. - means you are hiding your method at runtime. Output will be based base class method.
override for overriding. - means you are invoking your derived class method with the reference of base class. Output will be based on derived class method.
My version of explanation comes from using properties to help understand the differences.
override is simple enough, right ? The underlying type overrides the parent's.
new is perhaps the misleading (for me it was). With properties it's easier to understand:
public class Foo
{
public bool GetSomething => false;
}
public class Bar : Foo
{
public new bool GetSomething => true;
}
public static void Main(string[] args)
{
Foo foo = new Bar();
Console.WriteLine(foo.GetSomething);
Bar bar = new Bar();
Console.WriteLine(bar.GetSomething);
}
Using a debugger you can notice that Foo foo has 2 GetSomething properties, as it actually has 2 versions of the property, Foo's and Bar's, and to know which one to use, c# "picks" the property for the current type.
If you wanted to use the Bar's version, you would have used override or use Foo foo instead.
Bar bar has only 1, as it wants completely new behavior for GetSomething.
Not marking a method with anything means: Bind this method using the object's compile type, not runtime type (static binding).
Marking a method with virtual means: Bind this method using the object's runtime type, not compile time type (dynamic binding).
Marking a base class virtual method with override in derived class means: This is the method to be bound using the object's runtime type (dynamic binding).
Marking a base class virtual method with new in derived class means: This is a new method, that has no relation to the one with the same name in the base class and it should be bound using object's compile time type (static binding).
Not marking a base class virtual method in the derived class means: This method is marked as new (static binding).
Marking a method abstract means: This method is virtual, but I will not declare a body for it and its class is also abstract (dynamic binding).
using System;
using System.Text;
namespace OverrideAndNew
{
class Program
{
static void Main(string[] args)
{
BaseClass bc = new BaseClass();
DerivedClass dc = new DerivedClass();
BaseClass bcdc = new DerivedClass();
// The following two calls do what you would expect. They call
// the methods that are defined in BaseClass.
bc.Method1();
bc.Method2();
// Output:
// Base - Method1
// Base - Method2
// The following two calls do what you would expect. They call
// the methods that are defined in DerivedClass.
dc.Method1();
dc.Method2();
// Output:
// Derived - Method1
// Derived - Method2
// The following two calls produce different results, depending
// on whether override (Method1) or new (Method2) is used.
bcdc.Method1();
bcdc.Method2();
// Output:
// Derived - Method1
// Base - Method2
}
}
class BaseClass
{
public virtual void Method1()
{
Console.WriteLine("Base - Method1");
}
public virtual void Method2()
{
Console.WriteLine("Base - Method2");
}
}
class DerivedClass : BaseClass
{
public override void Method1()
{
Console.WriteLine("Derived - Method1");
}
public new void Method2()
{
Console.WriteLine("Derived - Method2");
}
}
}
I couldn't understand the need or purpose of "protected" when i have "virtual/override" could someone explain me what do i need those 2 things if they are almost the same.
Edit:
Thanks for all the helpers, i now understand that "protected" is only for visibility purposes, while virtual/override is for class behavior.
They are certainly not almost the same.
The protected modifier sets the visibility of a field or method: such a member can only be accessed from the class it is defined in or from a derived class.
The virtual modifier specifies that the method it is applied to can be overridden in a derived class.
These modifiers can be combined: a method can be protected and virtual.
protected means private for current class and derived classes
virtual means it can be used as-is but also be overridden in derived classes
Maybe it is better with some code instead of things you have probably already read, here is a little sample you can play with. Try removing the comments (//) and you can see that the compiler tells you that the properties cannot be accessed
[TestFixture]
public class NewTest
{
[Test]
public void WhatGetsPrinted()
{
A a= new B();
a.Print(); //This uses B's Print method since it overrides A's
// a.ProtectedProperty is not accesible here
}
}
public class A
{
protected string ProtectedProperty { get; set; }
private string PrivateProperty { get; set; }
public virtual void Print()
{
Console.WriteLine("A");
}
}
public class B : A
{
public override void Print() // Since Print is marked virtual in the base class we can override it here
{
//base.PrivateProperty can not be accessed hhere since it is private
base.ProtectedProperty = "ProtectedProperty can be accessed here since it is protected and B:A";
Console.WriteLine("B");
}
}
I can be argued that the Most important distinction about virtual, is that this causes the compiler, when calling a method member polymorphically, which implementation to bind the compiled code to. When you call a member of a class from client code where the actual type of the object is, say derived class foo, but the variable it is being called on is actually typed (declared) as some base class, say bar, Members declared as virtual will bind to the implementation in the actual object type, (or to the most derived base class of the objects type that has an implementation). Members not declared as virtual will bind to the implementation in the type that the variable is declared to be.
A. Virtual. then, if the member is declared as virtual, the implementation in the derived class will be executed even if the variable is declared as a base type.
public class Animal
{ public virtual Move() { debug.Print("Animal.Move()"); }
public class Bird: Animal
{ public virtual override Move() { debug.Print("Bird.Move()"); }
Animal x = new Bird();
x.Move(); // Will print "Bird.Move"
B. Not Virtual. When a member which is not declared as virtual, then the implementation will be chosen based on the declared type of the variable the method is executed on. So if you have a Bird Object, in variable x declared as `Animal', and you call a method that is implemented in both classes, the compiler will bind to the implementation in the Animal class, not in Bird, even though the object is really a Bird.
public class Animal
{ public Move() { debug.Print("Animal.Move()"); }
public class Bird: Animal
{ public Move() { debug.Print("Bird.Move()"); }
Animal x = new Bird();
x.Move(); // Will print "Animal.Move"
I think you need to understand above two things properly, since both has different purpose.
protected is the type or member can only be accessed by code in the same class or struct, or in a derived class.
The virtual keyword is for modify a method, property and allow it to be overridden in a derived class.
What is the difference between the override and new keywords in C# when defining methods in class hierarchies?
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 will shadow the method with a completely new method (which may or may not have the same signature) instead of overriding it (in which case the new method must have the same signature), meaning that polymorphism won't work. For example, you have these classes:
class A {
public virtual int Hello() {
return 1;
}
}
class B : A {
new public int Hello(object newParam) {
return 2;
}
}
class C : A {
public override int Hello() {
return 3;
}
}
If you do this:
A objectA;
B objectB = new B();
C objectC = new C();
Console.WriteLine(objectB.Hello(null)); // 2
Console.WriteLine(objectC.Hello()); // 3
objectA = objectB;
Console.WriteLine(objectA.Hello()); // 1
objectA = objectC;
Console.WriteLine(objectA.Hello()); // 3
Since you can define new method signatures with new, it's impossible for the compiler to know that the instance of A is actually an instance of B and the new method B defines should be available. new can be used when the parent object's method, property, field or event is not declared with virtual, and because of the lack of virtual the compiler won't “look up” the inherited method. With virtual and override, however, it works.
I would strongly recommend you avoid new; at best, it’s confusing, because you’re defining a method with a name that could be recognized as something else, and at worst, it can hide mistakes, introduce seemingly impossible bugs, and make extending functionality difficult.
Looks like an old question, let me try a different answer:
new : as the name says, it is a new member in the family of inheritance hierarchy and this will be used as base member for further down the chain (if marked as virtual).
override : It means I don't accept my parent class' member implementation and I will do differently.
Consider the following class hierarchy:
using System;
namespace ConsoleApp
{
public static class Program
{
public static void Main(string[] args)
{
Overrider overrider = new Overrider();
Base base1 = overrider;
overrider.Foo();
base1.Foo();
Hider hider = new Hider();
Base base2 = hider;
hider.Foo();
base2.Foo();
}
}
public class Base
{
public virtual void Foo()
{
Console.WriteLine("Base => Foo");
}
}
public class Overrider : Base
{
public override void Foo()
{
Console.WriteLine("Overrider => Foo");
}
}
public class Hider : Base
{
public new void Foo()
{
Console.WriteLine("Hider => Foo");
}
}
}
Output of above codes must be:
Overrider => Foo
Overrider => Foo
Hider => Foo
Base => Foo
A subclass overrides a virtual method by applying the override modifier:
If you want to hide a member deliberately, in which case you can apply the new modifier to the member in the subclass. The new modifier does nothing more than suppress the compiler warning that would otherwise result
override lets you override a virtual method in a base class so that you can put a different implementation in. new will hide a non-virtual method in a base class.
The simple difference is that override means the method is virtual (it goes in conduction with virtual keyword in base class) and new simply means it's not virtual, it's a regular override.
So both really are function overrides, one is with virtual characteristics, the other not.
What does mean exactly? It simply means polymorphism will not be in play for `new' methods.
The following image illustration might make this clear.
Note if you don't use new keyword, it is still implied but it will generate a warning message.
I'm pretty confused between some concepts of OOP: virtual, override, new and sealed override. Can anyone explain the differences?
I am pretty clear that if the derived class method is to be used, one can use the override keyword so that the base class method will be overriden by derived class. But I'm not sure about new, and sealed override.
The virtual keyword is used to modify a method, property, indexer or event declaration, and allow it to be overridden in a derived class. For example, this method can be overridden by any class that inherits it:
Use the new modifier to explicitly hide a member inherited from a base class. To hide an inherited member, declare it in the derived class using the same name, and modify it with the new modifier.
This is all to do with polymorphism. When a virtual method is called on a reference, the actual type of the object that the reference refers to is used to decide which method implementation to use. 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. For instance:
public class Base
{
public virtual void SomeMethod()
{
}
}
public class Derived : Base
{
public override void SomeMethod()
{
}
}
...
Base d = new Derived();
d.SomeMethod();
will end up calling Derived.SomeMethod if that overrides Base.SomeMethod.
Now, 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. In that case, code like this:
public class Base
{
public virtual void SomeOtherMethod()
{
}
}
public class Derived : Base
{
public new void SomeOtherMethod()
{
}
}
...
Base b = new Derived();
Derived d = new Derived();
b.SomeOtherMethod();
d.SomeOtherMethod();
Will first call Base.SomeOtherMethod , then Derived.SomeOtherMethod . They're effectively two entirely separate methods which happen to have the same name, rather than the derived method overriding the base method.
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).
An overriding property declaration may include the sealed modifier. Use of this modifier prevents a derived class from further overriding the property. The accessors of a sealed property are also sealed.
Any method can be overridable (=virtual) or not. The decision is made by the one who defines the method:
class Person
{
// this one is not overridable (not virtual)
public String GetPersonType()
{
return "person";
}
// this one is overridable (virtual)
public virtual String GetName()
{
return "generic name";
}
}
Now you can override those methods that are overridable:
class Friend : Person
{
public Friend() : this("generic name") { }
public Friend(String name)
{
this._name = name;
}
// override Person.GetName:
public override String GetName()
{
return _name;
}
}
But you can't override the GetPersonType method because it's not virtual.
Let's create two instances of those classes:
Person person = new Person();
Friend friend = new Friend("Onotole");
When non-virtual method GetPersonType is called by Friend instance it's actually Person.GetPersonType that is called:
Console.WriteLine(friend.GetPersonType()); // "person"
When virtual method GetName is called by Friend instance it's Friend.GetName that is called:
Console.WriteLine(friend.GetName()); // "Onotole"
When virtual method GetName is called by Person instance it's Person.GetName that is called:
Console.WriteLine(person.GetName()); // "generic name"
When non-virtual method is called the method body is not looked up - compiler already knows the actual method that needs to be called. Whereas with virtual methods compiler can't be sure which one to call, and it is looked up at runtime in the class hierarchy from down to up starting at the type of instance that the method is called on: for friend.GetName it looks starting at Friend class and finds it right away, for person.GetName class it starts at Person and finds it there.
Sometimes you make a subclass, override a virtual method and you don't want any more overrides down in the hierarchy - you use sealed override for that (saying you are the last one who overrides the method):
class Mike : Friend
{
public sealed override String GetName()
{
return "Mike";
}
}
But sometimes your friend Mike decides to change his gender and thus his name to Alice :) You could either change original code or instead subclass Mike:
class Alice : Mike
{
public new String GetName()
{
return "Alice";
}
}
Here you create a completely different method with the same name (now you have two). Which method and when is called? It depends on how you call it:
Alice alice = new Alice();
Console.WriteLine(alice.GetName()); // the new method is called, printing "Alice"
Console.WriteLine(((Mike)alice).GetName()); // the method hidden by new is called, printing "Mike"
When you call it from Alice's perspective you call Alice.GetName, when from Mike's - you call Mike.GetName. No runtime lookup is made here - as both methods are non-virtual.
You can always create new methods - whether the methods you are hiding are virtual or not.
This applies to properties and events too - they are represented as methods underneath.
By default a method cannot be overridden in a derived class unless it is declared virtual, or abstract. virtual means check for newer implementations before calling and abstract means the same, but it is guaranteed to be overridden in all derived classes. Also, no implementation is needed in the base class because it is going to be re-defined elsewhere.
The exception to the above is the new modifier. A method not declared virtual or abstract can be re-defined with the new modifier in a derived class. When the method is called in the base class the base method executed, and when called in the derived class, the new method is executed. All the new keywords allows you to do is to have two methods with the same name in a class hierarchy.
Finally a sealed modifier breaks the chain of virtual methods and makes them not overridable again. This is not used often, but the option is there. It makes more sense with a chain of 3 classes each deriving from the previous one
A -> B -> C
if A has an virtual or abstract method, that is overridden in B, then it can also prevent C from changing it again by declaring it sealed in B.
sealed is also used in classes, and that is where you will commonly encounter this keyword.
I hope this helps.
public class Base
{
public virtual void SomeMethod()
{
Console.WriteLine("B");
}
}
public class Derived : Base
{
//Same method is written 3 times with different keywords to explain different behaviors.
//This one is Simple method
public void SomeMethod()
{
Console.WriteLine("D");
}
//This method has 'new' keyword
public new void SomeMethod()
{
Console.WriteLine("D");
}
//This method has 'override' keyword
public override void SomeMethod()
{
Console.WriteLine("D");
}
}
Now First thing First
Base b=new Base();
Derived d=new Derived();
b.SomeMethod(); //will always write B
d.SomeMethod(); //will always write D
Now the keywords are all about Polymorphism
Base b = new Derived();
Using virtual in base class and override in Derived will give D(Polymorphism).
Using override without virtual in Base will give error.
Similarly writing a method (no override) with virtual will write 'B' with warning (because no polymorphism is done).
To hide such warning as in above point write new before that simple method in Derived.
new keyword is another story, it simply hides the warning that tells that the property with same name is there in base class.
virtual or new both are same except
new modifier
new and override cannot be used before same method or property.
sealed before any class or method lock it to be used in Derived class and it gives a compile time error.