How to achieve polymorphism in C# - c#

I am new to C#. I was trying to check that how polymorphism could be acheived in C# and I got confused that which one way of doing is achieving polymorphism . I am using the code given below and the output is A's method .
class A
{
public void Display()
{
Console.WriteLine("A's Method");
}
}
class B : A
{
public void Display()
{
Console.WriteLine("B's Method");
}
}
class Polymorphism
{
public static void Main(string[] args)
{
A a = new B();
a.Display();
Console.ReadKey();
}
}
But when I define Display() method as given below then output Method of B is called .
class A
{
public virtual void Display()
{
Console.WriteLine("A's Method");
}
}
class B : A
{
public override void Display()
{
Console.WriteLine("B's Method");
}
}
So By what way I am achieving Polymorphism and what is the difference between both of the way and which one should be preferable for overriding. Any help would be appreciable.

Virtual methods provide polymorphism, in that subclasses can override behavior. If you don't use virtual methods all you have are types that inherit what is defined in other types, but can't replace these inherited behaviors with new ones.
In the first case, A's method is called because you have a reference to an A, and non-virtual methods are resolved at compile time. The B object is allowed to be referenced by an A variable because B is-a A. (Note that downcasting the object and calling the result would invoke B's method: ((B)a).Display();.)
In the second case, B's method is called because the method is virtual, and virtual methods are resolved at run time, based on the actual type of the object, not the type of reference it happens to be stored in.

Simply put, Polymorphism is when you can treat a derived object as if it were an ancestor object, and have all derived functionality function correctly.
In your first example, you are hiding the ancestor method, so if you treat the derived object as an ancestor then it behaves as ancestor. This is not polymorphic.
In the second example, you are overriding the ancestor method, so when you treat the object as an ancestor it still behaves like the derived object. This is polymorphic.
While it's a simple concept, there are a lot of not so simple side-effects and conditions that go along with it. For example, see the Liskov Substitution Principle (which I won't go into here). There are other principles and theories at play as well. But, it's enough to understand that polymorphism in C# is achieved primarily via inheritance (although it can also be achieved via ducktyping with dynamic objects and with generic typing of generics).
There are also several types of polymorphism... see the Wikipedia entry for more:
http://en.wikipedia.org/wiki/Polymorphism_(computer_science)

In one case you are doing method hiding and in another you are overriding it.Don't hesitate to take help of google,you'll get very useful articles or answers.Even on SO,you'll get many similar questions.
class A
{
public void Display()
{
Console.WriteLine("A's Method");
}
}
class B : A
{
public void Display()
{
Console.WriteLine("B's Method");
}
}
In the above example,you are doing shadowing or method hiding.You can get the even the same result if you use new keyword like in below code.if you use don't write override in method of child class, the method in the derived class doesn't override the method in the base class, it merely hides it.
public new void Display()
{
Console.WriteLine("B's Method");
}
The override modifier is required to extend or modify the abstract or virtual implementation of an inherited method, property, indexer, or event.So to aceive overriding you have to use override keyword which you are using in second example.
Simply put, if a method is not overriding the derived method, it is hiding it.An override method provides a new implementation of a member that is inherited from a base class.
You can also check here on MSDN when to do method hiding or when to do overriding.
Based on discussion on comment section,i am attaching below code.Hope it'll help you.
using System;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
A a=new A();
a.Display();//Parent's Method
B b =new B();
b.Display();//Child's Method
**A ab = new B();
ab.Display();//Parent's Method**
Console.ReadKey();
Parent parent = new Parent();
parent.Display();//Parent's Method
Child child = new Child();
child.Display();//Child's Method
**Parent ParentChild = new Child();
ParentChild.Display();//Child's Method**
Console.ReadKey();
}
class A
{
public virtual void Display()
{
Console.WriteLine("Parent's Method");
}
}
class B : A
{
public void Display()
{
Console.WriteLine("Child's Method");
}
}
class Parent
{
public virtual void Display()
{
Console.WriteLine("Parent's Method");
}
}
class Child : Parent
{
public override void Display()
{
Console.WriteLine("Child's Method");
}
}
}
}

Related

How do I call a super class method from sub class object which has overridden?

I've been reading about Polymorphism and I've been through something interesting.
I have created two classes: a super class and a derived class. As you can see derived class inherits from the super class and using its method.
In the derived class I have overridden the method of super class.
So my question is: I want to call the super class method from an object of a derived class
For example:
derivedClass a = new derivedClass()
a.method();
I want a.methood() to execute the superclass method.
Is that possible?
Summing up your question: You have a base class and a derived class. The derived class overrides a virtual method of the base class. Given an instance of the derived class, is it possible to force a call to the base class version of the method, instead of the derived class?
Short answer: From inside the class, yes. From outside the class, no.
Essentially what you wish to do here is a non virtual call to a virtual method. It is legal to do a non-virtual call to a base class method, but only from inside the class:
class B
{
public virtual void M() { Console.WriteLine("B.M"); }
}
class D : B
{
public override void M() { Console.WriteLine("D.M"); }
public void BM() { base.M(); }
}
...
D d = new D();
d.M(); // D.M
d.BM(); // B.M
Now, for advanced players there are sneaky ways to call B.M with an instance of D as the receiver, and I'm not going to tell you what they are. You should not attempt to do so. The CLR may flag such attempts as violations of its "verified code" rules. The rules of virtual overriding are there for your convenience and safety. Do not attempt to do an end-run around those rules.
From outside the derived class it is not possible. From within the derived class it is.
If you have these classes defined:
class A
{
public virtual void Method1() { Console.WriteLine("A"); }
}
class B : A
{
override public void Method1() { Console.WriteLine("B"); }
public void BaseMethod1() { base.Method1(); }
}
You can execute the following:
B b = new B();
b.Method1(); //Outputs "B"
b.BaseMethod1(); //Outputs "A"
((A)b).Method1(); //***Outputs "B" (even though you cast it as A)
If you change overide to new then the output of the last line is "A"
You can try calling base method as per your requirement, if there is some condition, according to which you want to call it, you can use that condition as well.
public class SubClass : SuperClass
{
public bool IsCallBaseClassMethod { get; set; }
public override void Method(){
if (IsCallBaseClassMethod)
{
base.Method();
}
}
}
Set the condition according to your requirement for the object and call the method for same object.
SubClass testObject = new SubClass();
testObject.IsCallBaseClassMethod = true;
testObject.Method();

C# didnt call drived class function in polymorphism when pass parameter [duplicate]

Wondering what the difference is between the following:
Case 1: Base Class
public void DoIt();
Case 1: Inherited class
public new void DoIt();
Case 2: Base Class
public virtual void DoIt();
Case 2: Inherited class
public override void DoIt();
Both case 1 and 2 appear to have the same effect based on the tests I have run. Is there a difference, or a preferred way?
The override modifier may be used on
virtual methods and must be used on
abstract methods. This indicates for
the compiler to use the last defined
implementation of a method. Even if
the method is called on a reference to
the base class it will use the
implementation overriding it.
public class Base
{
public virtual void DoIt()
{
}
}
public class Derived : Base
{
public override void DoIt()
{
}
}
Base b = new Derived();
b.DoIt(); // Calls Derived.DoIt
will call Derived.DoIt if that overrides Base.DoIt.
The new modifier instructs the
compiler to use your child class implementation
instead of the parent class
implementation. Any code that is not
referencing your class but the parent
class will use the parent class
implementation.
public class Base
{
public virtual void DoIt()
{
}
}
public class Derived : Base
{
public new void DoIt()
{
}
}
Base b = new Derived();
Derived d = new Derived();
b.DoIt(); // Calls Base.DoIt
d.DoIt(); // Calls Derived.DoIt
Will first call Base.DoIt, then Derived.DoIt. They're effectively two entirely separate methods which happen to have the same name, rather than the derived method overriding the base method.
Source: Microsoft blog
virtual: indicates that a method may be overriden by an inheritor
override: overrides the functionality of a virtual method in a base class, providing different functionality.
new: hides the original method (which doesn't have to be virtual), providing different functionality. This should only be used where it is absolutely necessary.
When you hide a method, you can still access the original method by up casting to the base class. This is useful in some scenarios, but dangerous.
In the first case you are hiding the definition in the parent class. This means that it will only be invoked when you are dealing with the object as the child class. If you cast the class to its parent type, the parent's method will be invoked. In the second instance, the method is overridden and will be invoked regardless of whether the object is cast as the child or parent class.
new means respect your REFERENCE type(left-hand side of =) , thereby running reference types's method. If redefined method doesn't have new keyword, it is behaved as it has. Moreover, it also known as non-polymorphic inheritance. That is,
“I’m making a brand new method in the derived class that has
absolutely nothing to do with any methods by the same name in the base
class.” - by said Whitaker
override, which must be used with virtual keyword in its base class, means respect your OBJECT type(right-hand side of =), thereby
running method overriden in regardless of reference type. Moreover, it also known as polymorphic inheritance.
My way to bear in mind both keywords that they are opposite of each other.
override: virtual keyword must be defined to override the method. The method using override keyword that regardless of reference type(reference of base class or derived class) if it is instantiated with base class, the method of base class runs. Otherwise, the method of derived class runs.
new: if the keyword is used by a method, unlike override keyword, the reference type is important. If it is instantiated with derived class and the reference type is base class, the method of base class runs. If it is instantiated with derived class and the reference type is derived class, the method of derived class runs. Namely, it is contrast of override keyword. En passant, if you forget or omit to add new keyword to the method, the compiler behaves by default as new keyword is used.
class A
{
public string Foo()
{
return "A";
}
public virtual string Test()
{
return "base test";
}
}
class B: A
{
public new string Foo()
{
return "B";
}
}
class C: B
{
public string Foo()
{
return "C";
}
public override string Test() {
return "derived test";
}
}
Call in main:
A AClass = new B();
Console.WriteLine(AClass.Foo());
B BClass = new B();
Console.WriteLine(BClass.Foo());
B BClassWithC = new C();
Console.WriteLine(BClassWithC.Foo());
Console.WriteLine(AClass.Test());
Console.WriteLine(BClassWithC.Test());
Output:
A
B
B
base test
derived test
New code example,
Play with code by commenting in one-by-one.
class X
{
protected internal /*virtual*/ void Method()
{
WriteLine("X");
}
}
class Y : X
{
protected internal /*override*/ void Method()
{
base.Method();
WriteLine("Y");
}
}
class Z : Y
{
protected internal /*override*/ void Method()
{
base.Method();
WriteLine("Z");
}
}
class Programxyz
{
private static void Main(string[] args)
{
X v = new Z();
//Y v = new Z();
//Z v = new Z();
v.Method();
}
try following: (case1)
((BaseClass)(new InheritedClass())).DoIt()
Edit: virtual+override are resolved at runtime (so override really overrides virtual methods), while new just create new method with the same name, and hides the old, it is resolved at compile time -> your compiler will call the method it 'sees'
All combinations of none, virtual, override, new and abstract:
In case 1 if you used call the DoIt() method of the inherited class while the type is declared as the base class you will see the action of the base class even.
/* Results
Class1
Base1
Class2
Class2
*/
public abstract class Base1
{
public void DoIt() { Console.WriteLine("Base1"); }
}
public class Class1 : Base1
{
public new void DoIt() { Console.WriteLine("Class1"); }
}
public abstract class Base2
{
public virtual void DoIt() { Console.WriteLine("Base2"); }
}
public class Class2 : Base2
{
public override void DoIt() { Console.WriteLine("Class2"); }
}
static void Main(string[] args)
{
var c1 = new Class1();
c1.DoIt();
((Base1)c1).DoIt();
var c2 = new Class2();
c2.DoIt();
((Base2)c2).DoIt();
Console.Read();
}
The difference between the two cases is that in case 1, the base DoIt method does not get overridden, just hidden. What this means is that depending on the type of the variable depends on which method will get called. For example:
BaseClass instance1 = new SubClass();
instance1.DoIt(); // Calls base class DoIt method
SubClass instance2 = new SubClass();
instance2.DoIt(); // Calls sub class DoIt method
This can be really confusing and results in non expected behaviour and should be avoided if possible. So the preferred way would be case 2.
I had the same question and it's really confusing,
you should consider that override and new keywords working only with objects of type base class and value of derived class. In this case only you'll see the effect of override and new:
So if you have class A and B, B inherits from A, then you instantiate an object like this:
A a = new B();
Now on calling methods will take its state into consideration.
Override: means that it extends the function of the method, then it uses the method in the derived class, whereas new tell the compiler to hide the method in the derived class and use the method in the base class instead.
Here is a very good sight to that subject:
https://msdn.microsoft.com/EN-US/library/ms173153%28v=VS.140,d=hv.2%29.aspx?f=255&MSPPError=-2147217396
The article below is in vb.net but I think the explanation about new vs overrides is very easy to grasp.
https://www.codeproject.com/articles/17477/the-dark-shadow-of-overrides
At some point in the article, there is this sentence:
In general, Shadows assumes the function associated with the type is
invoked, while Overrides assumes the object implementation is
executed.
The accepted answer to this question is perfect but I think this article provide good examples to add better meaning about the differences between these two keywords.
If keyword override is used in derive class then its override the parent method.
If Keyword new is used in derive class then derive method hided by parent method.
Out of all those, new is the most confusing. Through experimenting, the new keyword is like giving developers the option to override the inheriting class implementation with the base class implementation by explicitly defining the type. It is like thinking the other way around.
In the example below, the result will return "Derived result" until the type is explicitly defined as BaseClass test, only then "Base result" will be returned.
class Program
{
static void Main(string[] args)
{
var test = new DerivedClass();
var result = test.DoSomething();
}
}
class BaseClass
{
public virtual string DoSomething()
{
return "Base result";
}
}
class DerivedClass : BaseClass
{
public new string DoSomething()
{
return "Derived result";
}
}
The functional difference will not be show in these tests:
BaseClass bc = new BaseClass();
bc.DoIt();
DerivedClass dc = new DerivedClass();
dc.ShowIt();
In this exmample, the Doit that is called is the one you expect to be called.
In order to see the difference you have to do this:
BaseClass obj = new DerivedClass();
obj.DoIt();
You will see if you run that test that in the case 1 (as you defined it), the DoIt() in BaseClass is called, in case 2 (as you defined it), the DoIt() in DerivedClass is called.
new : It just hides the method of the base class, but you can access it if you want.
override: It's overriding the base class's method and you can't access it even if you want to.
Example
using System;
public class Program
{
public static void Main()
{
BaseClass test = new DerivedClass();
var result = test.DoSomething();
Console.WriteLine(result);
}
class BaseClass
{
public string DoSomething()
{
return "Base result";
}
}
class DerivedClass : BaseClass
{
public new string DoSomething()
{
return "Derived result";
}
}
}
Result: Base result
P.S. I copied and slightly changed the above example from the following link:
https://stackoverflow.com/a/45822233/10995103

Inheritance chain with overriding and shadowing [duplicate]

Wondering what the difference is between the following:
Case 1: Base Class
public void DoIt();
Case 1: Inherited class
public new void DoIt();
Case 2: Base Class
public virtual void DoIt();
Case 2: Inherited class
public override void DoIt();
Both case 1 and 2 appear to have the same effect based on the tests I have run. Is there a difference, or a preferred way?
The override modifier may be used on
virtual methods and must be used on
abstract methods. This indicates for
the compiler to use the last defined
implementation of a method. Even if
the method is called on a reference to
the base class it will use the
implementation overriding it.
public class Base
{
public virtual void DoIt()
{
}
}
public class Derived : Base
{
public override void DoIt()
{
}
}
Base b = new Derived();
b.DoIt(); // Calls Derived.DoIt
will call Derived.DoIt if that overrides Base.DoIt.
The new modifier instructs the
compiler to use your child class implementation
instead of the parent class
implementation. Any code that is not
referencing your class but the parent
class will use the parent class
implementation.
public class Base
{
public virtual void DoIt()
{
}
}
public class Derived : Base
{
public new void DoIt()
{
}
}
Base b = new Derived();
Derived d = new Derived();
b.DoIt(); // Calls Base.DoIt
d.DoIt(); // Calls Derived.DoIt
Will first call Base.DoIt, then Derived.DoIt. They're effectively two entirely separate methods which happen to have the same name, rather than the derived method overriding the base method.
Source: Microsoft blog
virtual: indicates that a method may be overriden by an inheritor
override: overrides the functionality of a virtual method in a base class, providing different functionality.
new: hides the original method (which doesn't have to be virtual), providing different functionality. This should only be used where it is absolutely necessary.
When you hide a method, you can still access the original method by up casting to the base class. This is useful in some scenarios, but dangerous.
In the first case you are hiding the definition in the parent class. This means that it will only be invoked when you are dealing with the object as the child class. If you cast the class to its parent type, the parent's method will be invoked. In the second instance, the method is overridden and will be invoked regardless of whether the object is cast as the child or parent class.
new means respect your REFERENCE type(left-hand side of =) , thereby running reference types's method. If redefined method doesn't have new keyword, it is behaved as it has. Moreover, it also known as non-polymorphic inheritance. That is,
“I’m making a brand new method in the derived class that has
absolutely nothing to do with any methods by the same name in the base
class.” - by said Whitaker
override, which must be used with virtual keyword in its base class, means respect your OBJECT type(right-hand side of =), thereby
running method overriden in regardless of reference type. Moreover, it also known as polymorphic inheritance.
My way to bear in mind both keywords that they are opposite of each other.
override: virtual keyword must be defined to override the method. The method using override keyword that regardless of reference type(reference of base class or derived class) if it is instantiated with base class, the method of base class runs. Otherwise, the method of derived class runs.
new: if the keyword is used by a method, unlike override keyword, the reference type is important. If it is instantiated with derived class and the reference type is base class, the method of base class runs. If it is instantiated with derived class and the reference type is derived class, the method of derived class runs. Namely, it is contrast of override keyword. En passant, if you forget or omit to add new keyword to the method, the compiler behaves by default as new keyword is used.
class A
{
public string Foo()
{
return "A";
}
public virtual string Test()
{
return "base test";
}
}
class B: A
{
public new string Foo()
{
return "B";
}
}
class C: B
{
public string Foo()
{
return "C";
}
public override string Test() {
return "derived test";
}
}
Call in main:
A AClass = new B();
Console.WriteLine(AClass.Foo());
B BClass = new B();
Console.WriteLine(BClass.Foo());
B BClassWithC = new C();
Console.WriteLine(BClassWithC.Foo());
Console.WriteLine(AClass.Test());
Console.WriteLine(BClassWithC.Test());
Output:
A
B
B
base test
derived test
New code example,
Play with code by commenting in one-by-one.
class X
{
protected internal /*virtual*/ void Method()
{
WriteLine("X");
}
}
class Y : X
{
protected internal /*override*/ void Method()
{
base.Method();
WriteLine("Y");
}
}
class Z : Y
{
protected internal /*override*/ void Method()
{
base.Method();
WriteLine("Z");
}
}
class Programxyz
{
private static void Main(string[] args)
{
X v = new Z();
//Y v = new Z();
//Z v = new Z();
v.Method();
}
try following: (case1)
((BaseClass)(new InheritedClass())).DoIt()
Edit: virtual+override are resolved at runtime (so override really overrides virtual methods), while new just create new method with the same name, and hides the old, it is resolved at compile time -> your compiler will call the method it 'sees'
All combinations of none, virtual, override, new and abstract:
In case 1 if you used call the DoIt() method of the inherited class while the type is declared as the base class you will see the action of the base class even.
/* Results
Class1
Base1
Class2
Class2
*/
public abstract class Base1
{
public void DoIt() { Console.WriteLine("Base1"); }
}
public class Class1 : Base1
{
public new void DoIt() { Console.WriteLine("Class1"); }
}
public abstract class Base2
{
public virtual void DoIt() { Console.WriteLine("Base2"); }
}
public class Class2 : Base2
{
public override void DoIt() { Console.WriteLine("Class2"); }
}
static void Main(string[] args)
{
var c1 = new Class1();
c1.DoIt();
((Base1)c1).DoIt();
var c2 = new Class2();
c2.DoIt();
((Base2)c2).DoIt();
Console.Read();
}
The difference between the two cases is that in case 1, the base DoIt method does not get overridden, just hidden. What this means is that depending on the type of the variable depends on which method will get called. For example:
BaseClass instance1 = new SubClass();
instance1.DoIt(); // Calls base class DoIt method
SubClass instance2 = new SubClass();
instance2.DoIt(); // Calls sub class DoIt method
This can be really confusing and results in non expected behaviour and should be avoided if possible. So the preferred way would be case 2.
I had the same question and it's really confusing,
you should consider that override and new keywords working only with objects of type base class and value of derived class. In this case only you'll see the effect of override and new:
So if you have class A and B, B inherits from A, then you instantiate an object like this:
A a = new B();
Now on calling methods will take its state into consideration.
Override: means that it extends the function of the method, then it uses the method in the derived class, whereas new tell the compiler to hide the method in the derived class and use the method in the base class instead.
Here is a very good sight to that subject:
https://msdn.microsoft.com/EN-US/library/ms173153%28v=VS.140,d=hv.2%29.aspx?f=255&MSPPError=-2147217396
The article below is in vb.net but I think the explanation about new vs overrides is very easy to grasp.
https://www.codeproject.com/articles/17477/the-dark-shadow-of-overrides
At some point in the article, there is this sentence:
In general, Shadows assumes the function associated with the type is
invoked, while Overrides assumes the object implementation is
executed.
The accepted answer to this question is perfect but I think this article provide good examples to add better meaning about the differences between these two keywords.
If keyword override is used in derive class then its override the parent method.
If Keyword new is used in derive class then derive method hided by parent method.
Out of all those, new is the most confusing. Through experimenting, the new keyword is like giving developers the option to override the inheriting class implementation with the base class implementation by explicitly defining the type. It is like thinking the other way around.
In the example below, the result will return "Derived result" until the type is explicitly defined as BaseClass test, only then "Base result" will be returned.
class Program
{
static void Main(string[] args)
{
var test = new DerivedClass();
var result = test.DoSomething();
}
}
class BaseClass
{
public virtual string DoSomething()
{
return "Base result";
}
}
class DerivedClass : BaseClass
{
public new string DoSomething()
{
return "Derived result";
}
}
The functional difference will not be show in these tests:
BaseClass bc = new BaseClass();
bc.DoIt();
DerivedClass dc = new DerivedClass();
dc.ShowIt();
In this exmample, the Doit that is called is the one you expect to be called.
In order to see the difference you have to do this:
BaseClass obj = new DerivedClass();
obj.DoIt();
You will see if you run that test that in the case 1 (as you defined it), the DoIt() in BaseClass is called, in case 2 (as you defined it), the DoIt() in DerivedClass is called.
new : It just hides the method of the base class, but you can access it if you want.
override: It's overriding the base class's method and you can't access it even if you want to.
Example
using System;
public class Program
{
public static void Main()
{
BaseClass test = new DerivedClass();
var result = test.DoSomething();
Console.WriteLine(result);
}
class BaseClass
{
public string DoSomething()
{
return "Base result";
}
}
class DerivedClass : BaseClass
{
public new string DoSomething()
{
return "Derived result";
}
}
}
Result: Base result
P.S. I copied and slightly changed the above example from the following link:
https://stackoverflow.com/a/45822233/10995103

About virtual method in parent class C# [duplicate]

This question already has answers here:
Overriding vs method hiding [duplicate]
(3 answers)
Closed 8 years ago.
I think child class can override parent method which is not virtual
class Parent {
public void hello() {
Console.WriteLine("Hello Parent");
}
}
class Child:Parent{
public void hello() {
Console.WriteLine("Hello Child");
}
static void Main() {
Parent p = new Child();
Child c = new Child();
p.hello(); // Hello Parent
c.hello(); // Hello Child
}
}
So what different between virtual and not virtual in a parent method ???
In C#, virtual methods support polymorphism, by using a combination of the virtual and override keywords. With the virtual keyword on the base class method and the override keyword on the method in the derived class, both methods are said to be virtual.
Methods that don’t have either the virtual or override keywords, or that have the new keyword, are said to be non-virtual.
When a virtual method is invoked on an object, the run-time type of the object is used to determine which implementation of the method to use.
When a non-virtual method is invoked on an object, the compile-time type of the object is used to determine which implementation of the method to use.
In this case, you can use the new keyword
public new void hello()
{
Console.WriteLine("Hello Child");
}
Text taken from here
Read more about when to use override and new keyword
There is a big difference. I suggest you read this and carefully go through the examples.
To summarize, what you're dealing with is the difference between method overriding vs method hiding.
Method overriding allows a base type to access the behavior of the derived type's overridden functionality. This is what you're doing when you use the override keyword on a derived type's method where the base type's method is marked with the virtual keyword. On the other hand, using the same method signature on a more derived where the base type's method is not marked as virtual is what's known as method hiding. You can actually do this without using the new keyword, but you will get a compiler warning.
Method hiding loses the polymorphic benefits that method overriding provides, in that the methods of the derived class will use the "new" behavior of the hidden method, but base class will continue to use the base class's version of the method. The results of method hiding can seem pretty unintuitive and typically the effects are undesirable in OOP, but it does have its place. For instance, one of my favorite uses of method hiding is to allow for easier unit testing of protected methods.
The following code example is taken directly from the first link and succinctly illustrates one of the ways which method overriding differs from method hiding:
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");
}
}
The method hello() in the child class not override the hello method in the parent class. Child method just hide the implementation in parent class
Only methods marked as virtual can be overridden. Others can be hidden (using the new keyword), which isn't the same thing at all.
class Parent
{
public virtual int MyMethod()
{
return 1;
}
}
class Child : Parent
{
public override int MyMethod()
{
return 2;
}
}
class OtherChild : Parent
{
public new int MyMethod()
{
return 3;
}
}
// ...
Parent p = new Parent();
Parent c = new Child();
Parent oc = new OtherChild();
int result;
result = p.MyMethod(); // will return 1
result = c.MyMethod(); // will return 2
result = oc.MyMethod(); // will return 1
In the example above notice that every variables are declared as Parent. Calling the MyMethod on the first will simply return the basic implementation. Calling it on the second one calls the override found in Child class. The third one, however, being declared Parent, doesn't know about the implementation of MyMethod within OtherChild class and calls the one it knows: in Parent.
If you want to learn more on polymorphism, I suggest you have a look at this article on Wikipedia:
Polymorphism (computer science)
problem is with your testing code, power of virtual comes this way (if you set your method to virtual):
Parent p = new Parent();
Parent c = new Child();
Console.WriteLine(p.hello()); //Prints Hello Parent
Console.WriteLine(c.hello()); //Prints Hello Child
if you keep it unvirtual, both lines would print hello parent
kinda real world example is this:
Vehicle p = new Vehicle();
Vehicle c = new Car();
Console.WriteLine(p.Drive()); //Prints "Default Vehicle"
Console.WriteLine(c.Drive()); //Prints "Car"

Is it possible to override a non-virtual method?

Is there any way to override a non-virtual method? or something that gives similar results (other than creating a new method to call the desired method)?
I would like to override a method from Microsoft.Xna.Framework.Graphics.GraphicsDevice with unit testing in mind.
No, you cannot override a non-virtual method. The closest thing you can do is hide the method by creating a new method with the same name but this is not advisable as it breaks good design principles.
But even hiding a method won't give you execution time polymorphic dispatch of method calls like a true virtual method call would. Consider this example:
using System;
class Example
{
static void Main()
{
Foo f = new Foo();
f.M();
Foo b = new Bar();
b.M();
}
}
class Foo
{
public void M()
{
Console.WriteLine("Foo.M");
}
}
class Bar : Foo
{
public new void M()
{
Console.WriteLine("Bar.M");
}
}
In this example both calls to the M method print Foo.M. As you can see this approach does allow you to have a new implementation for a method as long as the reference to that object is of the correct derived type but hiding a base method does break polymorphism.
I would recommend that you do not hide base methods in this manner.
I tend to side with those who favor C#'s default behavior that methods are non-virtual by default (as opposed to Java). I would go even further and say that classes should also be sealed by default. Inheritance is hard to design for properly and the fact that there is a method that is not marked to be virtual indicates that the author of that method never intended for the method to be overridden.
Edit: "execution time polymorphic dispatch":
What I mean by this is the default behavior that happens at execution time when you call virtual methods. Let's say for example that in my previous code example, rather than defining a non-virtual method, I did in fact define a virtual method and a true overridden method as well.
If I were to call b.Foo in that case, the CLR would correctly determine the type of object that the b reference points to as Bar and would dispatch the call to M appropriately.
No you can't.
You can only override a virtual method - see the MSDN here:
In C#, derived classes can contain methods with the same name as base class methods.
The base class method must be defined virtual.
You can't override non-virtual method of any class in C# (without hacking CLR), but you can override any method of interface the class implements.
Consider we have non-sealed
class GraphicsDevice: IGraphicsDevice {
public void DoWork() {
Console.WriteLine("GraphicsDevice.DoWork()");
}
}
// with its interface
interface IGraphicsDevice {
void DoWork();
}
// You can't just override DoWork in a child class,
// but if you replace usage of GraphicsDevice to IGraphicsDevice,
// then you can override this method (and, actually, the whole interface).
class MyDevice: GraphicsDevice, IGraphicsDevice {
public new void DoWork() {
Console.WriteLine("MyDevice.DoWork()");
base.DoWork();
}
}
And here's demo
class Program {
static void Main(string[] args) {
IGraphicsDevice real = new GraphicsDevice();
var myObj = new MyDevice();
// demo that interface override works
GraphicsDevice myCastedToBase = myObj;
IGraphicsDevice my = myCastedToBase;
// obvious
Console.WriteLine("Using real GraphicsDevice:");
real.DoWork();
// override
Console.WriteLine("Using overriden GraphicsDevice:");
my.DoWork();
}
}
If the base class isn't sealed then you can inherit from it and write a new method that hides the base one (use the "new" keyword in the method declaration). Otherwise no, you cannot override it because it was never the original authors intent for it to be overridden, hence why it isn't virtual.
I think you're getting overloading and overriding confused, overloading means you have two or more methods with the same name but different sets of parameters while overriding means you have a different implementation for a method in a derived class (thereby replacing or modifying the behaviour in it's base class).
If a method is virtual, you can override it using the override keyword in the derrived class. However, non-virtual methods can only hide the base implementation by using the new keyword in place of the override keyword. The non-virtual route is useless if the caller accesses the method via a variable typed as the base type as the compiler would use a static dispatch to the base method (meaning the code in your derrived class would never be called).
There is never anything preventing you from adding an overload to an existing class, but only code that knows about your class would be able to access it.
The answer to this question is not entirely No. It depends on how you structure your inheritance and access the instances of your classes. If your design meets the following, you would be able to override non-virtual method from base class with the new modifier:
The method is declared in an interface that your classes inherit from
You are accessing the class instances using the interface
Take example of the following:
interface ITest { void Test(); }
class A : ITest { public void Test(){Console.WriteLine("A");} }
class B : A { public new void Test(){Console.WriteLine("B");} }
ITest x = new B();
x.Test(); // output "A"
calling x.Test() will output "A" to the console. However if you re-declare the interface in the definition of class B, x.Test() will output B instead.
interface ITest { void Test(); }
class A : ITest { public void Test(){Console.WriteLine("A");} }
class B : A, ITest { public new void Test(){Console.WriteLine("B");} }
ITest x = new B();
x.Test(); // output "B"
In the case you are inheriting from a non-derived class, you could simply create an abstract super class and inherit from it downstream instead.
Is there any way to override a non-virtual method? or something that gives similar results (other than creating a new method to call the desired method)?
You cannot override a non-virtual method. However you can use the new modifier keyword to get similar results:
class Class0
{
public int Test()
{
return 0;
}
}
class Class1 : Class0
{
public new int Test()
{
return 1;
}
}
. . .
// result of 1
Console.WriteLine(new Class1().Test());
You will also want to make sure that the access modifier is also the same, otherwise you will not get inheritance down the line. If another class inherits from Class1 the new keyword in Class1 will not affect objects inheriting from it, unless the access modifier is the same.
If the access modifier is not the same:
class Class0
{
protected int Test()
{
return 0;
}
}
class Class1 : Class0
{
// different access modifier
new int Test()
{
return 1;
}
}
class Class2 : Class1
{
public int Result()
{
return Test();
}
}
. . .
// result of 0
Console.WriteLine(new Class2().Result());
...versus if the access modifier is the same:
class Class0
{
protected int Test()
{
return 0;
}
}
class Class1 : Class0
{
// same access modifier
protected new int Test()
{
return 1;
}
}
class Class2 : Class1
{
public int Result()
{
return Test();
}
}
. . .
// result of 1
Console.WriteLine(new Class2().Result());
As pointed out in a previous answer, this is not a good design principle.
There is a way of achieving this using abstract class and abstract method.
Consider
Class Base
{
void MethodToBeTested()
{
...
}
void Method1()
{
}
void Method2()
{
}
...
}
Now, if you wish to have different versions of method MethodToBeTested(), then
change Class Base to an abstract class and method MethodToBeTested() as an abstract method
abstract Class Base
{
abstract void MethodToBeTested();
void Method1()
{
}
void Method2()
{
}
...
}
With abstract void MethodToBeTested() comes an issue; the implementation is gone.
Hence create a class DefaultBaseImplementation : Base to have the default implementation.
And create another class UnitTestImplementation : Base to have unit test implementation.
With these 2 new classes, the base class functionality can be overridden.
Class DefaultBaseImplementation : Base
{
override void MethodToBeTested()
{
//Base (default) implementation goes here
}
}
Class UnitTestImplementation : Base
{
override void MethodToBeTested()
{
//Unit test implementation goes here
}
}
Now you have 2 classes implementing (overriding) MethodToBeTested().
You can instantiate the (derived) class as required (i.e. either with base implementation or with unit test implementation).

Categories