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
Related
I'm trying to refresh my memory but can't find answers with Google.
public class BaseClass
{
public virtual void DoSomething()
{
Trace.Write("base class");
}
}
public class DerivedClass : BaseClass
{
public override void DoSomething()
{
Trace.Write("derived class");
}
}
If I create an instance of derived class, how do I convert it to it's base class so that when DoSomething() is called, it uses the base class's method only?
A dynamic cast still calls the derived class's overridden method:
DerivedClass dc = new DerivedClass();
dc.DoSomething();
(dc as BaseClass).DoSomething();
Output: "derived class"
Although this sounds irrational but it works
DerivedClass B = new DerivedClass();
BaseClass bc = JsonConvert.DeserializeObject<BaseClass>(JsonConvert.SerializeObject(B));
You can't - that's entirely deliberate, as that's what polymorphism is all about. Suppose you have a derived class which enforces certain preconditions on the arguments you pass to an overridden method, in order to maintain integrity... you don't want to be able to bypass that validation and corrupt its internal integrity.
Within the class itself you can non-virtually call base.AnyMethod() (whether that's the method you're overriding or not) but that's okay because that's the class itself deciding to potentially allow its integrity to be violated - presumably it knows what it's doing.
You absolutely CAN (call the base method), just read up on Polymorphism:
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/polymorphism
Example:
public class BaseClass
{
public void DoWork() { }
public int WorkField;
public int WorkProperty
{
get { return 0; }
}
}
public class DerivedClass : BaseClass
{
public new void DoWork() { }
public new int WorkField;
public new int WorkProperty
{
get { return 0; }
}
}
And how to call it:
DerivedClass B = new DerivedClass();
B.DoWork(); // This calls the new method.
BaseClass A = (BaseClass)B;
A.DoWork(); // This calls the old method.
Try using the new keywor instead of override As far as i know this should enable that desired behavior.
I'm not realy sure about that so please don't blame me if i'm wrong!
public class BaseClass
{
public virtual void DoSomething()
{
Trace.Write("base class");
}
}
public class DerivedClass : BaseClass
{
public new void DoSomething()
{
Trace.Write("derived class");
}
}
The solutions with new instead of override break the polymorphism. Recently I came to the same problem and implemented it the following way. My solution has the following advantages:
virtual and override stays in place;
name BaseClass is not used directly in the type cast, so if I introduce an intermediate MiddleClass in the hierarchy between BaseClass and DerivedClass, which also implements DoSomething(); then the MiddleClass's implementation won't be skipped.
This is the implementation:
public class BaseClass
{
public virtual void DoSomething()
{
Trace.Write("base class");
}
}
public class DerivedClass : BaseClass
{
public override void DoSomething()
{
Trace.Write("derived class");
}
public void BaseDoSomething()
{
base.DoSomething();
}
}
The usage is:
DerivedClass dc = new DerivedClass();
dc.DoSomething();
dc.BaseDoSomething();
For VB.net, I've used the following code to do the conversion (shown with Lists of Objects):
Dim tempPartialList As New List(Of clsBaseData)
For Each iterClsDerivedData As clsDerivedData In ListOfDerivedDataObjects
tempPartialList.Add(CType(iterClsDerivedData, clsBaseData))
Next
Where clsBaseData is the Base Class from which clsDerivedData is made by Inheriting clsBaseData.
ListOfDerivedDataObjects is a List(Of clsDerivedData).
I have found this useful where I have Lists of several Derived Classes and I would like to operate on a property of the Base Class for all the objects in the Lists of Derived Classes. The tempPartialList is, for me, a temporary List meant to facilitate changing this property.
I 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.
}
}
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.
I am trying understand the need of override and virtual in C#,so I wrote the following code:
using System;
namespace Override
{
class Base
{
public virtual void method()
{
Console.WriteLine("Base method");
}
}
class Derived : Base
{
public override void method()
{
Console.WriteLine("Derived method");
}
}
class Program
{
static void Main(string[] args)
{
Derived d = new Derived();
d.method();
}
}
}
And I was expecting "Derived method" to be called and printed.Then I wrote the following code without using virtual/override combination.
using System;
namespace Override
{
class Base
{
public void method()
{
Console.WriteLine("Base method");
}
}
class Derived : Base
{
public void method()
{
Console.WriteLine("Derived method");
}
}
class Program
{
static void Main(string[] args)
{
Derived d = new Derived();
d.method();
}
}
}
And I got the same result i.e. "Derived method" called and printed.My question is if the code worked without virtual/override as I expected,what is the need of them? or am I missing something here?
In your source code, you are always doing simple inheritance without any polymorphic behavior. You are always created instance of derived class and assigning it to derived class instance variable.
DerivedClass d = new DerivedClass(); // here no polymorphism, and only inheritance is there
So When you will call method using class variable, it will always call DerivedClass method, no matter if the method is virtual or not in parent class.
In Polymorphism, your programs do not know the exact type of class on which you are calling the method (this concept is called late-binding). As in example below:
BaseClass b = new DerivedClass(); // here b is a base class instance but initiated using derived class
After calling b.method() it will do late binding and will show polymorphic behavior (only if the method has been set virtual in the base class)
NOTE: The virtual keyword delays binding to correct version of method to runtime and is core keywork to implement polyphorphism. So for exact polymorphic behavior, declare methods as virtual in parent class, and then in child class, ovverride that method.
virtual allows the correct version of the method to be chosen at runtime, based on information not available at compile time. Consider the following tweak to your example:
using System;
namespace Override
{
class Base
{
public virtual void method()
{
Console.WriteLine("Base method");
}
}
class Derived : Base
{
public override void method()
{
Console.WriteLine("Derived method");
}
}
class Program
{
static void Main(string[] args)
{
Derived d = new Derived();
Base b = d;
b.method();
}
}
}
With virtual/override, this code will display Derived method, as at runtime we can see that b is really a Derived instance. Without virtual/override, it will display Base method, as the declared type of b is Base.
Here is the test you are missing:
Base d = new Derived();
d.method(); // "Derived method"
Base b = new Base();
b.method(); // "Base method"
Also imagine if you had a collection of Base objects that were composed of different inherited objects. The virtual keyword allows those Base objects to understand what type they really are at runtime.
List<Base> collection = new List<Base>();
collection.Add(new Base());
collection.Add(new Derived()};
collection.Add(new Base());
foreach(Base b in collection)
{
b.method(); // will print out "Base" or "Derived" correctly
}
see the DIFFERENCE
class Base
{
public void method()
{
Console.WriteLine("Base method");
}
}
class Derived : Base
{
public void method()
{
Console.WriteLine("Derived method");
}
}
class Program
{
static void Main(string[] args)
{
Derived d;
d = new Derived();
d.method();
d = new Base();
d.method();
}
}
OUTPUT :
Derived method
Derived method
class Base
{
public virtual void method()
{
Console.WriteLine("Base method");
}
}
class Derived : Base
{
public override void method()
{
Console.WriteLine("Derived method");
}
}
class Program
{
static void Main(string[] args)
{
Derived d;
d = new Derived();
d.method();
d = new Base();
d.method();
}
}
OUTPUT :
Derived method
Base method
Base class pointers can be used to point to object of the base class or any object derived from the base. So the need of virtual methods come into picture when base class object point to derived class
Base d = new Derived();
d.method(); // "Derived method"
The method 'method' on the Derived class will hide the implementation of the Base class which is why you got the messaged "Derived method".
There are many uses of virtual and abstract but one example is where you have functionality in the base class which may not fit all cases of classes that inherit from your base class. Using virtual allows another class to completely override that functionality and provide its own implementation.
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