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.
Related
I'm overriding some existing codes but try not to touch the existing classes.
I have a base class
public class A {
public virtual void Func() {
do something...
}
}
I have several other classes is accessing it by calling A.Func()
I'm writing an extension class
public class B : A {
public override void Func() {
do something else...
}
}
Without touching the base and those classes calling the base class, is there any way to point the method Func() to the extended class?
I mean when there's a class calling A.Func(), it executes the B.Func() instead A.Func()
But without touching the code from that class nor the A class
An example
public class C {
void SomeOutsideFunc()
{
var a = new A();
a.Func(); //in here, is it possible to execute the extended B class's Func()?
}
}
in above example
class A and class C is forbidden for any modification
class B is an extended class I coded.
right now, I have to make another override to class C to make things working
my issue is there are a lot of C type classes (none of those that I can make any changes)
tks
You can create the object of base class which is pointing to the child class, suppose B.
A objA=new B();
objA.Func();
This will call the function of derived class.
What you're describing is how things already work. Imagine you have these two classes:
public class BaseClass
{
public virtual void WriteSomething()
{
Console.WriteLine("base write something");
}
}
public class DerivedClass : BaseClass
{
public override void WriteSomething()
{
Console.WriteLine("derived write something");
}
}
If you create an instance of BaseClass and call WriteSomething, you get "base write something":
BaseClass instance = new BaseClass();
instance.WriteSomething();
// "base write something" is printed to the console
Likewise, creating an instance of DerivedClass and calling WriteSomething results in "derived write something":
DerivedClass instance = new DerivedClass();
instance.WriteSomething();
// "derived write something" is printed to the console
Even if we assign that instance to a BaseClass variable, we still get "derived write something":
DerivedClass instance = new DerivedClass();
BaseClass instanceAsBaseClass = instance;
instanceAsBaseClass.WriteSomething();
// "derived write something" is printed to the console
So we can clearly then pass this into a method as BaseClass but still use the overriden methods from the derived class:
public static void DoSomeThings(BaseClass instance)
{
instance.WriteSomething();
}
BaseClass instance = new DerivedClass();
DoSomeThings(instance);
// "derived write something" is printed to the console
Note that we haven't changed the DoSomeThings method.
Try it online
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 am brand new to base classes so please correct me if I am wrong or I should be doing this another way, but I have coded a simple code snippet below that explains what I want to do.
class A : B
{
private int _classId;
public A (int id) : base(id)
{
_classId = id;
}
public string GetString()
{
return "This will eventually be an important string.";
}
}
class B
{
private int _classId;
public B (int id)
{
// here I want to be able to get access to class A's methods
// such as GetString() ...
}
public void SomeMethod()
{
}
}
So what I want to do is allow B to get A's methods.
Reason for doing this?
I don't want to populate the class A because B is going to have a lot of methods so it would be cleaner to keep them in B then just get them from A in other code. Am I doing this wrong? is this not what base classes do? I simply just want to be able to still do this:
A.SomeMethodInB();
Without populating class A with junk and making it cleaner by storing it in class B
Let me summarize your question:
You want a method that is only implemented in a descendant class (A)
You want this method to be available to both the base class (B) and the descendant class (A)
You want the base class to be able to call the descendant class' implementation of the method
This is the original definition of polymorphism (lately people have been using the term much more generally) and is bread-and-butter when it comes to OOP. It is also the hardest area of OOP to grasp for newcomers.
Write a base class with a virtual method
Let us start with the base class. Notice I have changed your example slightly, for a reason I will explain in a moment.
class B
{
virtual protected string GetString()
{
return "I am a B";
}
public void DoSomethingWithGetString()
{
Console.WriteLine(GetString());
}
}
In this example, DoSomethingWithGetString calls GetString. Note that GetString is virtual. This tells the compiler that we don't want to decide where the implementation of GetString is until runtime. This means it can't be bound at compile time: instead, its location is identified by a runtime Virtual Method Table that is set up when the object is created. If this code is running as part of a instance of class B, then it will call class B's implementation of GetString. But if this code was inherited, and is actually being called by some other object that descends from class B, it will call that class' version of GetString. This is called late binding.
Write the descendant class
So now let's write class A:
class A : B
{
protected override GetString()
{
return "I am an A.";
}
}
Because A descends from B, we don't need to implement anything else. If we call A.DoSomethingWithGetString it'll actually call B's implementation because it is inherited.
Execute it
If you run this code
var a = new A();
a.DoSomethingWithGetString(); //Output = "I am an A"
...the following will happen:
An instance of A, which descends from B, is created
The VMT of A is configured so that calls to GetString are sent to A.GetString.
You call A.DoSomethingWithGetString
This call is directed to B's code base, because A doesn't implement it.
The code base in B detects that GetString is a virtual method, and calls it using the VMT.
The VMT points to A's implementation of GetString.
A.GetString is executed.
Thus you have an situation where code in class B is calling code in class A, which is what you asked for.
You can also run it this way:
B b = new A();
b.DoSomethingWithGetString(); //Output = "I am an A"
Thus you have a pointer to a B that says it's an A, because it is using a VMT set up for class A.
But I don't want any implementation in class B
Now, let's say you don't want class B to have any implementation at all for GetString, but you still want to be able to call the implementation in A. There is a way to do this using an abstract virtual method. Simply add the abstract keyword and remove the implementation:
abstract class B
{
abstract protected string GetString(); //Notice no implementation
public void DoSomethingWithGetString()
{
Console.WriteLine(GetString());
}
}
Of course, now you can't use class B by itself, because it requires an implementation of GetString that will only be present in a descendant class. So you can no longer create an instance of B directly; you have to subtype, and use the subtype.
Can't use constructor
Now, you'll notice in my example I removed your constructor calls. There is a reason for this. A constructor should not ever call a method that is defined on a descendant class. The reason: during construction, constructors are called up and down the inheritance hierarchy, starting with the base class and moving down the descendant chain. That means, when you call B's constructor, A's constructor has not been called yet. if A's constructor hasn't run yet, we can't be sure that A has been properly set up yet, and therefore it is a really bad idea to call any of its methods.
There are some workarounds for this, but that is a topic for a different question.
If the method is only defined in Class A, then there is no way to access it through Class B.
If the method exists in both Class A and Class B, then you can use virtual method and override.
Think it is better to use the names BaseClass and DerivedClass in an example. The names A and B are kind of arbitrary. Although A comes before B, the names don't imply the direction of inheritance intended.
class Program
{
static void Main(string[] args)
{
var bc = new BaseClass(3);
var dc = new DerivedClass(5);
Console.WriteLine("Base Class Method A: " + bc.MethodA());
Console.WriteLine("Derived Class Method A: " + dc.MethodA());
Console.WriteLine("Base Class Method B: " + bc.MethodB());
Console.WriteLine("Derived Class Method B: " + dc.MethodB());
Console.ReadLine();
}
}
public class BaseClass {
protected int _classId;
public BaseClass(int classId) {
_classId = classId;
}
public virtual string MethodA() {
return "Method A in base class: " + _classId.ToString();
}
public string MethodB()
{
return "I am a method B in the base class: " + _classId.ToString();
}
}
public class DerivedClass : BaseClass {
public DerivedClass(int classId)
: base(classId)
{
}
public override string MethodA() {
return "Method A in derived class: " + _classId.ToString();
}
}
There are two ways you can go about this. Let me first set out an example.
Here we have the base class that contains a method:
public class Base
{
public void BaseMethod()
{
// Some method.
}
}
Here is the derived class, where we want to call the method:
public class DerivedClass : BaseClass
{
// We want to use BaseMethod() here.
}
In order to call a method from the base class, we use the base keyword.
public class DerivedClass : BaseClass
{
base.BaseMethod();
}
This is fine if you want to just call the base method. However, if we want to change the method and define it with a different function, we have to declare it as virtual in the base class, as so:
public class Base
{
public virtual void BaseMethod()
{
// Some method.
}
}
In the derived class, we can now use the keyword override to override the virtual method of the base class, which redefines it to do something else:
public class DerivedClass : BaseClass
{
public override void BaseMethod()
{
// Some new function.
}
}
The new Keyword is used to hide the base class implementation of the same. But I am not sure why the following code produces the output as Baseclass
class Baseclass
{
public void fun()
{
Console.Write("Base class" + " ");
}
}
class Derived1: Baseclass
{
new void fun()
{
Console.Write("Derived1 class" + " ");
}
}
class Derived2: Derived1
{
new void fun()
{
Console.Write("Derived2 class" + " ");
}
}
class Program
{
public static void Main(string[ ] args)
{
Derived2 d = new Derived2();
d.fun();
}
}
We are hiding the implementation of fun in derived2 but still Base class is called why so? Am I missing something?
Derived2.funis private (it is the default access modifier of the members of the type). It is not visible outside the class. Only visible fun method outside the class is Baseclass.fun and thus it is invoked.
You need to make your Derived2.fun visible outside the class to get the expected output. You can do it by either making it public/internal.
Generally, hiding in C# works like this: the "hider" (a method or field or whatever declared with the new keyword) takes over all "functionality" it can from whatever is being "hidden". For example:
class Baseclass
{
public void fun()
{
Console.Write("Base class" + " ");
}
}
class Derived1 : Baseclass
{
new public void fun()
{
Console.Write("Derived1 class" + " ");
}
}
Here, fun in Derived1 hides fun in Baseclass completely, because they have exactly the same "functionality": they are both methods, and are both public, i.e. available from anywhere.
However, if the "hider" doesn't cover all of the "hidden" member's functionality, it will still be there, ready to do its job. Example:
class Baseclass
{
public void fun()
{
Console.Write("Base class" + " ");
}
}
class Derived1 : Baseclass
{
new public int fun;
}
Here, Baseclass.fun is a method, and Derived1.fun is a field.
You can access the "hiding" field in an assignment expression like this: int a = new Derived1().fun;. As it is hiding the base class method fun, you cannot access it (the method) this way: System.Action a = new Derived1().fun; fails.
But what happens if we do something to fun that an int field can't do? new Derived1().fun(); will work, calling the fun in the base class!
This specific example is even mentioned on MSDN on the new Modifier page:
Generally, a constant, field, property, or type that is introduced in a class or struct hides all base class members that share its name. There are special cases. For example, if you declare a new field with name N to have a type that is not invocable, and a base type declares N to be a method, the new field does not hide the base declaration in invocation syntax.
Your case is very similar. The fun methods in your two derived classes are hiding just part of the original fun in the base class. If you call fun from inside Derived1 or Derived2, you will end up with the "hider" version of foo of the respective class. However, when you call foo from outside your three classes, the public method of Baseclass is called, because its public functionality has not been hidden...
Well, originally I had a couple of constants (like MAX_SPEED) with different values in every of the derived classes. The idea was to use those values in some methods of the base class. That's when I realized that I cannot do that with constants, so I created read-only properties.
I need a method to assign those values to private fields at the moment of the instantiation, preferably in the base class. But first I have to assing the original values in derived classes. Since those are properties, I couldn't find a way to initialize them while defining, so the only way to do that is in the derived constructors.
That's where the problem comes: values are initialized after their assigning to private fields in the base class. The solution I get away with is to create a virtual method and to do assigning there.
Is there a way to call a base constructor from derived class so that the code from derived constructor will be invoked first?
class BaseClass
{
public BaseClass()
{
System.Console.WriteLine("This should be shown after");
}
}
class DerivedClass : BaseClass
{
public DerivedClass() : base()
{
System.Console.WriteLine("This should be shown first");
}
}
Of course in the example it would work the other way around. Is there a solution?
No. The base class constructor is always executed before the body of the derived class constructor. However:
Any instance variable initializers in the derived class are executed before the base class constructor
The base class constructor can execute virtual methods which can be overridden in the derived class. This is almost always a bad idea though. (All kinds of normal preconditions are invalid at this point. You can observe readonly variables which haven't been set yet because they'll be set in the constructor body, for example. Ick.)
To demonstrate both of these:
using System;
class BaseClass
{
public BaseClass()
{
VirtualMethod();
Console.WriteLine("BaseClass ctor body");
}
public virtual void VirtualMethod()
{
Console.WriteLine("BaseClass.VirtualMethod");
}
}
class DerivedClass : BaseClass
{
int ignored = ExecuteSomeCode();
public DerivedClass() : base()
{
Console.WriteLine("DerivedClass ctor body");
}
static int ExecuteSomeCode()
{
Console.WriteLine("Method called from initializer");
return 5;
}
public override void VirtualMethod()
{
Console.WriteLine("DerivedClass.VirtualMethod");
}
}
class Test
{
static void Main()
{
new DerivedClass();
}
}
Output:
Method called from initializer
DerivedClass.VirtualMethod
BaseClass ctor body
DerivedClass ctor body
Additionally, if your base class constructor takes a parameter, then you can execute some code in the derived class in order to provide an argument:
DerivedClass() : base(SomeStaticMethod())
All of these are fairly smelly though. What's your specific situation?
No, you can't do that. Base classes are always initialized first. However, you can do something like this:
class BaseClass
{
public BaseClass()
{
this.Initialize();
}
protected virtual void Initialize()
{
System.Console.WriteLine("This should be shown after");
}
}
class DerivedClass : BaseClass
{
public DerivedClass() : base()
{
}
protected override void Initialize()
{
System.Console.WriteLine("This should be shown first");
base.Initialize();
}
}
One more option is to make child class constructor as static , so that it executes first than parent class constructor. but it not preferable it violates the oop design