Inheritance in C# - override and virtual - c#

I'm new to C# override and virtual. In the following example I want to call Callee method in B class from Caller method in A class. B inherits A. Any thoughts?
namespace Blah
{
public class Program
{
public static void Main(string[] args)
{
A a = new A();
a.Caller();
}
}
class A
{
public void Caller()
{
Console.WriteLine("In Caller");
Callee(); // How to make this call B:Callee() and make it print "in B"
}
public virtual void Callee()
{
Console.Write("In A");
}
}
class B : A
{
public override void Callee()
{
Console.Write("In B");
}
}
}

If you want to call the Callee method inside class B, you have first to create an instance of this class and then call this method:
var b = new B();
B.Callee();
If that is you are looking for (despite it does not make sense from a practical prespective), you should place the above two lines inside the method Caller in class A.
Usually we define a base class and if we think that a method in the class we define can be re-implemented from classes that would be derived from our class, we mark the method as virtual. When we derive a class from our base class and we do not override the virtual method, then the method that has been defined in the base class is called. Whereas when we have overriden a virtual method defined in a base class, the method in the derived class is called.

In your example you have the baseclass A with a subclass B that overrides a method in A. This means that you create an alternative A, that can interact as an A but might have different behavior.
However, this does not mean that every instance of A suddenly starts to use this definition. In your example you create a hard instance of A, but as the overriding method is in B it will never be called.
Instead you should create an instance of B, which you can cast to an A. Allowing your code to treat it as an A object, even though its B.
In your example, the only thing you'll need to do is create an instance of B (fiddle):
A a = new B();
a.Caller();
// Prints:
// In Caller
// In B
The way this works is more or less the same as Java inheritance, only in C# you need to mark methods as virtual in order to override them.
However, if your intention was to change definition of Callee in A without having to create a B (so new A().Caller()would print out "In B"), you should rethink whatever you are trying to do. It is something completely different from virtual methods and in most situations something you should try to avoid.

Related

Confusing about hiding method c# [duplicate]

Can anybody tell the working of overriding and hiding in terms of memory and references.
class A
{
public virtual void Test1() { //Impl 1}
public virtual void Test2() { //Impl 2}
}
class B : A
{
public override void Test1() { //Impl 3}
public new void Test2() { Impl 4}
}
static Main()
{
A aa=new B() //This will give memory to B
aa.Test1(); //What happens in terms of memory when this executes
aa.Test2(); //-----------------------SAME------------------------
}
Here memory is with class B but in the second statement aa.Test2 class A's method will be called. Why is it? If B has memory then B's method should be called (in my point of view).
Any link / exercise that describes this fundamental very deeply and completely will be a big help.
Take a look at this answer to a different question by Eric Lippert.
To paraphrase (to the limits of my comprehension), these methods go into "slots". A has two slots: one for Test1 and one for Test2.
Since A.Test1 is marked as virtual and B.Test1 is marked as override, B's implementation of Test1 does not create its own slot but overwrites A's implementation. Whether you treat an instance of B as a B or cast it to an A, the same implementation is in that slot, so you always get the result of B.Test1.
By contrast, since B.Test2 is marked new, it creates its own new slot. (As it would if it wasn't marked new but was given a different name.) A's implementation of Test2 is still "there" in its own slot; it's been hidden rather than overwritten. If you treat an instance of B as a B, you get B.Test2; if you cast it to an A, you can't see the new slot, and A.Test2 gets called.
To add to #Rawling's answer, practical examples could be shown using an example such as this:
class Base
{
// base property
public virtual string Name
{
get { return "Base"; }
}
}
class Overriden : Base
{
// overriden property
public override string Name
{
get { return "Overriden"; }
}
}
class New : Base
{
// new property, hides the base property
public new string Name
{
get { return "New"; }
}
}
1. Overriding
In case of the overriden property, base class' virtual method's slot is replaced by a different implementation. Compiler sees the method as virtual, and must resolve its implementation during run-time using the object's virtual table.
{
Base b = new Base();
Console.WriteLine(b.Name); // prints "Base"
b = new Overriden();
// Base.Name is virtual, so the vtable determines its implementation
Console.WriteLine(b.Name); // prints "Overriden"
Overriden o = new Overriden();
// Overriden.Name is virtual, so the vtable determines its implementation
Console.WriteLine(o.Name); // prints "Overriden"
}
2. Hiding
When a method or a property is hidden using the new keyword, the compiler creates a new non-virtual method for the derived class only; base class' method remains untouched.
If the type of the variable is Base (i.e. only contains the virtual method), its implementation will be resolved through the vtable. If the type of the variable is New, then the non-virtual method or property will be invoked.
{
Base b = new Base();
Console.WriteLine(b.Name); // prints "Base"
b = new New();
// type of `b` variable is `Base`, and `Base.Name` is virtual,
// so compiler resolves its implementation through the virtual table
Console.WriteLine(b.Name); // prints "Base"
New n = new New();
// type of `n` variable is `New`, and `New.Name` is not virtual,
// so compiler sees `n.Name` as a completely different property
Console.WriteLine(n.Name); // prints "New"
}
3. Summary
If a part of your code accepts the base type, it will always use the virtual table during run-time. For most OOP scenarios, this means that marking a method as new is very similar to giving it a completely different name.
4. Object sizes after instantiation
Note that instantiating any of these types doesn't create a copy of the virtual table. Each .NET object has a couple of bytes of header and a pointer to the virtual table of table of its type (class).
Regarding the new property (the one which is not virtual), it is basically compiled as a static method with thiscall semantics, meaning that it also doesn't add anything to the size of the instance in memory.
Already answered at here
Overriding is the definition of multiple possible implementations of the same method signature, such that the implementation is determined by the runtime type of the zeroth argument (generally identified by the name this in C#).
Hiding is the definition of a method in a derived type with a signature identical to that in one of its base types without overriding.
The practical difference between overriding and hiding is as follows:
Hiding is for all other members (static methods , instance members, static members). It is based on the early binding . More clearly , the method or member to be called or used is decided during compile time.
•If a method is overridden, the implementation to call is based on the run-time type of the argument this.
•If a method is simply hidden, the implementation to call is based on the compile-time type of the argument this.
Here are some samples : Example # 1. and Example # 2
Test1() method in class A and test1() method in class B will executes according to MethdOverriding.
Test2() method in class A and test2() method in class B will executes according to Method Hiding.
In method Overriding the child class members will execute, and in Method Hiding the Parent class members will execute.
Put simply when overriding a method or property the override method must have the same signature as the base method. When hiding this is not required, the new object can take any form as shown below
// base
public int GrossAmount { get; set; }
// hiding base
public new string GrossAmount
{
get;
set;
}
Deducting from the code provided you should have B:A.
You can hide a method in case when you want create your own implementation of the (say) method of the base class, which can not be overriden, cause, say, it's not virtual.
In my expirience, I used hiding mostly for debug purposes.
For example when I don't know who sets the property of some 3rd prt component, whom code is not available to me. So what I do is:
create a child class from the component
hide the property of interest with new keyword
put the breakpoint in set
and wait when it will be hit.
Sometimes, very useful and helps me get information in fast way, especially in first stage when you're learning new components, frameworks, libraries.. whatever.
By hiding a method or a property you are simply stating that you want to stop such method being polymorphic when you have an object of that type. Additionally hidden methods are called in a non polymorphic way so to call these method type has to be know at compile time, as it was a simply non virtual method.
public class BaseClass
{
public void PrintMethod()
{
Console.WriteLine("Calling base class method");
}
}
public class ChildClass
{
public new void PrintMethod()
{
Console.WriteLine("Calling the child or derived class method");
}
}
class Program
{
static void Main()
{
BaseClass bc = new ChildClass();
bc.PrintMethod();
}
}
Method Hiding is that when Base Class reference variable pointing to a child class object. It will invoke the hidden method in base Class.
Where as, When We declare virtual method in the base class. We override that method in the derived or child class. Then Base Class reference variable will call the derived class method. This is called Method Overriding.
class Base {
int a;
public void Addition() {
Console.WriteLine("Addition Base");
}
public virtual void Multiply()
{
Console.WriteLine("Multiply Base");
}
public void Divide() {
Console.WriteLine("Divide Base");
}
}
class Child : Base
{
new public void Addition()
{
Console.WriteLine("Addition Child");
}
public override void Multiply()
{
Console.WriteLine("Multiply Child");
}
new public void Divide()
{
Console.WriteLine("Divide Child");
}
}
class Program
{
static void Main(string[] args)
{
Child c = new Child();
c.Addition();
c.Multiply();
c.Divide();
Base b = new Child();
b.Addition();
b.Multiply();
b.Divide();
b = new Base();
b.Addition();
b.Multiply();
b.Divide();
}
}
Output : -
Addition Child
Multiply Child
Divide Child
Addition Base
Multiply Child
Divide Base
Addition Base
Multiply Base
Divide Base
At the time of overriding the compiler checks the object of the class but in
in hiding compiler only checks the reference of the class

Why can't I call a public method in the subclass from the superclass when the object is of the subclass type?

I have a class B that is a subclass of class A. I create an object of type B and call OnlyA() on it, but inside OnlyA() the call to OnlyB() causes a compiler error.
From my understanding, OnlyB() is the same as this.OnlyB() and the method called should be chosen from the object's class (B), not the current class where code is being executed (A). This is why the call to Both() calls the method in B, not A. So why is it searching for OnlyB() in A, not B? How am I supposed to know when the method called is chosen from the object's class or the current class?
class Program
{
static void Main(string[] args)
{
B bRefB = new B();
bRefB.OnlyA();
}
}
class A
{
public void OnlyA()
{
Console.WriteLine("In A - OnlyA()");
OnlyB(); // compiler error
Both(); // calls the method in B
}
public virtual void Both()
{
Console.WriteLine("In A - Both()");
}
}
class B : A
{
public void OnlyB()
{
Console.WriteLine("In B - OnlyB()");
}
public override void Both()
{
Console.WriteLine("In B - Both()");
}
}
You are absolutely correct that OnlyB is the same as this.OnlyB. And that's the issue; this is of type A. It has no knowledge that B even exists (nor should it).
Superclasses do not, and are not supposed to, have any knowledge about the fact that they have derived classes at all let alone what methods are in them. Its not an issue of "searching"; what happens when you have C that doesn't define OnlyB? What method would be called?
Subclasses on the other hand are always subclasses of the super class; and so it is safe for them to invoke base class methods.
Bradely's answer covers why your code does not work (this is of type A). Here is correct way to write your requirements as code.
You want to call method based on run-time type of an object. Since compile time of this is type of the current object you need to cast it in some way to derived type before calling. Possible options:
just cast - statically checked that B has OnlyB, cast exception at run-time:
((B)this).OnlyB();
use dynamic - no static type checking, exception at run time if actual class does not have OnlyB method irrespective if it is from B, C...
dynamic b = this;
b.OnlyB();
manual reflection call (same as dynamic).
generics - see Curiously Recurring Template Pattern and generics constraints (C#)

Virtualism Inherited in C#

I picked this code form MSDN resources in C# polymorphism.
public class A
{
public virtual void DoWork() { }
}
public class B : A
{
public override void DoWork() { }
}
public class C : B
{
public override void DoWork()
{
// Call DoWork on B to get B's behavior:
base.DoWork();
// DoWork behavior specific to C goes here:
// ...
}
}
It says class C is overriding the DoWork() of B, but the DoWork() method of class B is not made virtual. Since C inherits all methods and data of B, does it also inherit the virtual methods of A (which are available in B, as A is the base class for B)?
What if B does not provide an implementation of DoWork() then would C be accessing the copy of A's virtual method directly to override it?
Also, when C inherits from B does it get a separate copy of A's members or the copy of those of B.
I guess for separate copy of A's members one has to inherit A separately, like
public class C : A, B
Correct me if wrong.
EDIT :
public class A
{
public virtual void DoWork()
{
Console.WriteLine("In Class A");
}
}
public class B : A
{
public void DoWork() { Console.WriteLine("In Class B"); }
}
public class C : B
{
public void DoWork()
{
Console.WriteLine("In Class C");
base.DoWork();
}
}
When I run this on VS C#, virtual keyword is not reqd. in class B's DoWork(), and override keyword in class B's and C's DoWork(), as it generates only a tip-off warning. So does it mean just specifying which base class is being derived in the class name definition as in public class C : B is enough to qualify he methods o be virtual in nature?
Also, since C# doesnot provide with the option of multiple inheritance of classes, is there a way to directly use A's implementation of DoWork() from C's class without explicitly creating an object of A and then accessing DoWork() using it?
It says class C is overriding the DoWork() of B, but the DoWork() method of class B is not made virtual.
When you override a virtual method, it "stays" virtual unless you explicitly seal it with sealed. (You can only specify the sealed modifier for a method if it's also an override method.)
What if B does not provide an implementation of DoWork() then would C be accessing the copy of A's virtual method directly to override it?
Yes. Or rather, it would invoke A's implementation at execution time. It's not really a "copy".
Also, when C inherits from B does it get a separate copy of A's members
It's not really clear what you mean here. What sort of "copy" are you talking about, and which members? If you mean which fields are in each object, then it's just the union of the fields declared in all the classes up the inheritance chain.
EDIT: In your edited code, you're not overriding anything. You're declaring new methods, which aren't called polymorphically. So if you write:
A a = new C();
a.DoWork();
that will just print "In Class A" - whereas if B and C overrode the virtual method, it would print "In Class C" and then "In Class B".
Also, since C# doesnot provide with the option of multiple inheritance of classes, is there a way to directly use A's implementation of DoWork() from C's class without explicitly creating an object of A and then accessing DoWork() using it?
Assuming this is in the case where B overrides DoWork, no. That would break encapsulation - it could break the invariants of B, for example.
C is inheriting from B, this means it can override all virtual methods in B. Override means method is still virtual.
If B would not give any implementation for DoWork, then base.DoWork in C's implementation would call the implementation in A class - as normally virtual behaves. You should not assume that your base call will be call to exactly B method and no other - it's implementation detail that could be changed in future. Important thing is it will call nearet parent implementation of DoWork.
And finally - when inheriting B, you also get all the properties, methods and everything inherited from A. In C# there is nothing like multiple inheritance (meaning C : A, B where C, A and B are classes will not work). You cannot get separate copy or anything of A with inheritance - you just get what's in B (which of course includes things that B has inherited from A and so on).

C# inheritance and virtual functions confusion

Today I came up with an interesting problem. I noticed that the following code:
class A
{
public A()
{
Print();
}
public virtual void Print()
{
Console.WriteLine("Print in A");
}
}
class B : A
{
public B()
{
Print();
}
public override void Print()
{
Console.WriteLine("Print in B");
}
}
class Program
{
static void Main(string[] args)
{
A a = new B();
}
}
Prints
Print in B
Print in B
I want to know why does it print the "Print in B" twice.
I want to know why does it print the "Print in B" twice.
You're calling a virtual method twice, on the same object. The object is an instance of B even during A's constructor, and so the overridden method will be called. (I believe that in C++, the object only "becomes" an instance of the subclass after the base class constructor has executed, as far as polymorphism is concerned.)
Note that this means that overridden methods called from a constructor will be executed before the derived class's constructor body has had a chance to execute. This is dangerous. You should almost never call abstract or virtual methods from a constructor, for precisely this reason.
EDIT: Note that when you don't provide another constructor call to "chain" to using either : this(...) or : base(...) in the constructor declaration, it's equivalent to using : base(). So B's constructor is equivalent to:
public B() : base()
{
Print();
}
For more on constructor chaining, see my article on the topic.
Unlike C++ where calls of virtuals in the constructor are restricted to the definition within the class itself, the overrides are fully honored in C#'s constructors. The practice is frowned upon, and for a good reason (link), but it is still allowed: A's constructor calls the override supplied by B, producing the output that you see. This is the normal behavior of overriden virtual functions.
Because B override's the Print method. Your variable a is of type B, and B's Print method looks like this:
public override void Print()
{
Console.WriteLine("Print in B");
}
If you do not call a base class constructor, the default constructor for the base class will be called implicitly (MSDN).
You would not get the double output if you defined your class A constructors this way:
class A
{
public A()
{
// does nothing
}
public A(object a)
{
Print();
}
}
The reason it prints "Print in B" both times is that Print() is overridden in the class B so B.Print() is what is called by both constructors.
I think you can force the A.Print() to be called in the A constructor as follows:
class A
{
public A()
{
((A)this).Print();
}
}
Hope this helps.
Because you have an instance of B which overrides Print, so that overridden method gets called. Also, A's ctor will run, followed by B's which is why it gets printed twice.

How method hiding works in C#?

Why the following program prints
B
B
(as it should)
public class A
{
public void Print()
{
Console.WriteLine("A");
}
}
public class B : A
{
public new void Print()
{
Console.WriteLine("B");
}
public void Print2()
{
Print();
}
}
class Program
{
static void Main(string[] args)
{
var b = new B();
b.Print();
b.Print2();
}
}
but if we remove keyword 'public' in class B like so:
new void Print()
{
Console.WriteLine("B");
}
it starts printing
A
B
?
When you remove the public access modifier, you remove any ability to call B's new Print() method from the Main function because it now defaults to private. It's no longer accessible to Main.
The only remaining option is to fall back to the method inherited from A, as that is the only accessible implementation. If you were to call Print() from within another B method you would get the B implementation, because members of B would see the private implementation.
You're making the Print method private, so the only available Print method is the inherited one.
Externally, the new B.Print()-method isn't visible anymore, so A.Print() is called.
Within the class, though, the new B.Print-method is still visible, so that's the one that is called by methods in the same class.
when you remove the keyword public from class b, the new print method is no longer available outside the class, and so when you do b.print from your main program, it actually makes a call to the public method available in A (because b inherits a and a still has Print as public)
Without the public keyword then the method is private, therefore cannot be called by Main().
However the Print2() method can call it as it can see other methods of its own class, even if private.

Categories

Resources