Below code, A is base class and B is a derived class. When I do A a1 = new B(); and call what a1 can see, I see that it can only see class A field because a1 is of A type so it can not see B specific members and this is what I expected too. But when I call a1.Display() it prints out B's display method. How come a1 can not see B field but can reach B's display method?
using System;
namespace Test
{
class A
{
public int varOfClassA = 5;
public virtual void Display()
{
Console.WriteLine("I am Class A");
}
}
class B : A
{
public int varOfClassB = 10;
public override void Display()
{
Console.WriteLine("I am class B");
}
}
class Program
{
static void Main(string[] args)
{
A a1 = new B();
Console.WriteLine(a1.varOfClassA); //prints out "5"
a1.Display(); //prints out "I am class B" why???
}
}
}
That's because the method Display() is declared in B as overrides.
Every member that overrides a base class member will be executed whether the reference type is of the derived or of the base class.
When you do A a1 = new B(); what you have is an instance of B, not an instance of A.
However, since the reference is of type A, you can only access whatever methods of B that also exists in A, either inherited as is or overridden.
As a rule, in such cases, when your code executes a method on a1, the method that gets executed is the B method, since that's the type of instance you have. However, this rule does have an exception - and that is when instead of override, the method in B is declared as new. In such cases, the method (or property) of A is executed, even though your instance is of type B:
class A
{
public virtual void Display()
{
Console.WriteLine("I am Class A");
}
public int MyIntValue { get{ return 5; } }
}
class B : A
{
public override void Display()
{
Console.WriteLine("I am class B");
}
public new int MyIntValue { get{ return 5; } }
}
Using the above classes:
A a1 = new B();
a1.Display(); // Displays "I am class B"
Console.WriteLine(a1.MyIntValue.ToString()); // Displays "5"
You can see a live demo on rextester.
Related
In the below program, since new keyword is used in the derived class, I am expecting the output "C" but am getting the output as "A". Can some one please explain the reason behind this?
Also, I would like to know how to invoke Foo method declared in the class C.
class A
{
public void Foo()
{
Console.Write("A");
}
}
class B : A
{
new void Foo()
{
Console.Write("B");
}
}
class C : B
{
new void Foo()
{
Console.Write("C");
}
}
public static void Main(string[] args)
{
C c = new C();
c.Foo();
}
C.Foo() has no visibility on the private Foo you new'ed up inside C - it will call the public derived Foo from A.
class C : B
{
public void Test()
{
// this has visibility on the private new'ed up method and can call it
this.Foo();
}
// this is just a private method - it does NOT shadow the public one
// "new" does nothing valuable here
new void Foo()
{
Console.Write("C");
}
}
public static void Main(string[] args)
{
C c = new C();
c.Foo(); // calls the public visible derived A.Foo
c.Test(); // this will call the "new"ed up C.Foo()
}
Output:
AC
You can call private methods only from inside the class they belong to - not from the outside (unless you put the call to the private one inside a public method - see Test).
Most of the time new-ing up a method (to me) is a code smell.
The keyword new in this context prevents inheritance, i.e., it hides the inherited methods instead of providing a new implementation of them. There are only rare situations where you want to do this. Mainly for static members, since those can't be overridden.
The right way to inherit and possibly override methods is to make them virtual:
class A
{
public virtual void Foo()
{
Console.Write("A");
}
}
class B : A
{
public override void Foo()
{
Console.Write("B");
}
}
class C : B
{
public override void Foo()
{
Console.Write("C");
}
}
Now, your test will work as expected. It will even work if you assign the new C to variable typed as A:
A a = new C();
a.Foo(); // Prints: C
That being said, your Foo methods in B and C don't have a public modifier and are thus private. I.e., you can only access A.Foo, which is public, from the outside.
public class Program
{
public static void Main()
{
var type = new C().getType();
type.Foo();
}
public class A
{
public void Stop()
{
// do something
}
}
public class B : A
{
public void Foo()
{
Console.WriteLine("Foo");
}
}
public class D : A
{
public void Bar()
{
Console.WriteLine("Bar");
}
}
public class C
{
public A getType()
{
if (some condition)
return new B();
if (some condition)
return new D();
return A();
}
}
}
-EDIT-
I updated the code, so now we have two child classes B and D, both have different methods inside them, however since they inherit A, they at least both have access to Stop() method. The problem with making an abstract method Foo() and Bar() inside the parent class A is that, B should not have access to Bar() and D should not have access to Foo(), but by making an abstract method they will need to implement them both.
I know that I can check the type of the returned object inside Main() method and then cast it to that type. But this won't be convenient as in the future I will have more descendants of A.
Is it in my situation ok, to use dynamic? Because that would solve the problem and would be very convenient.
public class C
{
public dynamic getType()
{
if (some condition)
return new B();
if (some condition)
return new D();
return A();
}
}
You almost had it right:
public class Program
{
public static void Main()
{
var type = new C().getType();
type.Foo();
}
public abstract class A
{
public abstract void Foo();
}
public class B : A
{
public override void Foo()
{
Console.WriteLine("Foo");
}
}
public class C
{
public A getType()
{
return new B();
}
}
}
You need a Foo method in A that B can override. I have made A.Foo abstract, which means we do not have to define a base implementation of A.Foo. The A class is declared abstract to prevent someone trying to create an instance of it.
If you want derived classes to inherit a base implementation of Foo from A, then declare Foo as virtual in A. So in the following example, class B overrides the base Foo, whereas class C inherits the base Foo:
public class Program
{
public static void Main()
{
A a1 = new B();
a1.Foo(); // Outputs "B.Foo".
A a2 = new C();
a2.Foo(); // Outputs "A.Foo".
}
public abstract class A
{
public virtual void Foo()
{
Console.WriteLine("A.Foo");
}
}
public class B : A
{
public override void Foo()
{
Console.WriteLine("B.Foo");
}
}
public class C : A
{
}
}
You are confusing the type of a variable and the type of the runtime object it will be pointing to (given its a reference type, with value types, there is no such distinction).
When you declare a variable, you are defining the type of the variable:
Foo a = ... //a is of type Foo at compile time.
What you assign to that variable doesn't matter at all (unless you are using implicitly typed variables with var)
But given the following code:
object o = new Foo();
Now you can see the diferrence; the variable o is of type object but the runtime object it will be pointing to is of type string.
In your question you are asking why you cant do the following:
var stringLength = o.Length; //o is a string isn't it?
Why? Isn't o really a string. Yes, but that information is only availabe at runtime, the compiler knows nothing of what will happen at runtime, it only knows that o is of type object and object has no Length property. The only thing the compiler will make sure of is that the types are compatible; it will let you assign a Giraffe to an Animal typed variable but it won't let you assing a Car.
If you've got this clear, then you'll understando why this doesn't make sense:
But I did explicitly return B inside getType() method, why does it not have access to Foo()?
Because the method getType return type is A not B, not C and not D.
Consider this code in C#:
public class A
{
public A()
{
Console.WriteLine("A");
}
public virtual void One()
{
Console.WriteLine("One of A");
}
public virtual void Two()
{
One();
}
}
public class B : A
{
public B()
{
Console.WriteLine("B");
}
public override void One()
{
Console.WriteLine("One of B");
}
public override void Two()
{
Console.WriteLine("Two of B");
}
public void Three()
{
base.Two();
}
}
and the main:
A a3 = new B(); //"A" and then "B"
a3.Two();' //"Two of B"
((B)a3).Three(); //"One of B"
Why does the last line in the main program writes 'One of B'?
Why when it executes One() it goes to the One() of B?
Break down what each method calls -
((B)a3).Three();
calls
B.Three();
which calls
A.Two();
which calls
A.One();
but A.One is virtual, which means that the system has to look at the actual type of the object at runtime to determine which One will be called.
Since the object referenced by a3 is a B (even though you declared it as an A variable reference), B.One() is called.
Because your variable a3 is type B, and because type A's Two method is marked as virtual, the compiler infers that the method that should be called is type B's overridden implementation of One().
Because method One() of class A is declared virtual and it finds an override in class B, so it picks the override.
Could someone please explain what the difference is between these two examples?
Class A
protected virtual string GetData()
Class B
private override string GetData()
And the following:
Class A
protected string GetData()
Class B
private string GetData()
Assuming that 'Class B' inherits from 'Class A'.
I always assumed that you need to use virtual in the superclass and override in the subclass if you want overriding of a method, however I tried removing the keywords and the program compiled fine. What exactly is the difference, if any?
The second example that you showed hides the GetData of the parent, it doesn't override it.
Example:
private class Base
{
public virtual void Test()
{
Console.WriteLine("Base");
}
public void Test2()
{
Console.WriteLine("Base");
}
}
private class Derived : Base
{
public override void Test()
{
Console.WriteLine("Derived");
}
public void Test2()
{
Console.WriteLine("Derived");
}
}
static void Main()
{
Base b = new Base();
Derived d = new Derived();
Base dInB = new Derived();
b.Test();
d.Test();
dInB.Test();
b.Test2();
d.Test2();
dInB.Test2();
Console.ReadKey(true);
}
It outputs:
Base // Base.Test()
Derived // Derived.Test()
Derived // Derived.Test()
Base // Base.Test2()
Derived // Derived.Test2()
Base // You think you're calling Derived.Test2(), but you actually call Base.Test2()
Actually this sample is invalid, because it should use the new keyword in public new void Test2() in the Derived class.
It works just like operator overloading. It doesn't actually override anything. When you have the exact type Derived it calls the new method.
You have to be really careful with hiding members, it is nothing like overriding (classes) or implementing (interfaces) at all. Only when you have the exact type it'll call a new method, otherwise it'll still call the base type's method!
The difference is that in the first case you are overriding and in the second case you are hiding which is completely different.
In the first case:
class B: A
{
void Foo()
{
B b = new B();
A a = b;
a.GetData() //B's GetData() will be called
b.GetData() //B's GetData() will be called
}
}
On the other hand in the second case:
class B: A
{
void Foo()
{
B b = new B();
A a = b;
a.GetData() //A's GetData() will be called
b.GetData() //B's GetData() will be called
}
}
In the second case you are simply hiding A's implementation of GetData() but you will always be able to call A's implementation through a variable typed A even if the variable refers to a instance of type B. Note that this is completely different from how overriding behaves.
public class A
{
public virtual string GetData() { return "A";}
}
public class B : A
{
public override string GetData() { return "B"; }
}
What do you expect if you are using the classes as in the following codeblock?
A a = new A();
B b = new B();
A c = new B();
Console.WriteLine(a.GetData());
Console.WriteLine(b.GetData());
Console.WriteLine(c.GetData());
This will print "A" "B" "B". The variable c is stored as A type but when executing the method the code is resolved to the "real" implementation. (see google for virtual function table and resolving principle)
If you do not use virtual and override as in the code below this will print "A" "B" "A".
public class A
{
public string GetData() { return "A";}
}
public class B : A
{
public new string GetData() { return "B"; }
}
I'm trying to override an overridden method (if that makes sense!) in C#.
I have a scenario similar to the below, but when I have a breakpoint in the SampleMethod() in the "C" class it's not being hit, whilst the same breakpoint in the "B" method is being hit.
public class A
{
protected virtual void SampleMethod() {}
}
public class B : A
{
protected override void SampleMethod()
{
base.SampleMethod();
}
}
public class C : B
{
protected override void SampleMethod()
{
base.SampleMethod();
}
}
Thanks in advance!
Edit:
Ok, the context would help:
This is in the context of a composite control so class A inherits from CompositeControl and calls SampleMethod() after overriding the CreateChildControls() method.
Overriding can be performed in a chain as long as you like. The code you have shown is correct.
The only possible explanation for the behaviour you are seeing is that the object to which you are referring is actually of type B. I suggest that you double check this, and if things still don't make sense, post the other appropiate code.
Without seeing the code that calls SampleMethod, my guess would be that you have an object of type B and call SampleMethod on that.
The breakpoint is more than likely not being hit because you actually instantiated an instance of the "B" class.
Method override resolution works based on the actual runtime type of the class whose method should be called. So, if you had the following code:
C c = new C();
c.SampleMethod();
and the following:
C c = new C();
B b = (B)c;
b.SampleMethod();
both the runtime types of the class whose SampleMethod will be called is type B.
That solution works fine; although to actually use it outside the class the method is in, you need to set the access of SampleMethod to public rather than protected in all of the cases it appears, so:
public class A
{
public virtual void SampleMethod()
{
Console.WriteLine("lol");
}
}
public class B : A
{
public override void SampleMethod()
{
base.SampleMethod();
}
}
public class C : B
{
public override void SampleMethod()
{
base.SampleMethod();
}
}
for Overriding more than once in the hierarchy use something like this
// abstract class
abstract class A
{
public abstract void MethodOne();
}
// class B inherits A
class B : A
{
public override void MethodOne()
{
Console.WriteLine("From Class B");
}
}
// class C inherits B
class C : B
{
public override void MethodOne()
{
Console.WriteLine("From Class C");
}
}
// class D inherits C
class D : C
{
public override void MethodOne()
{
Console.WriteLine("From Class D");
}
}
// etc......
// class Main method Class
class MainClass
{
public static void Main()
{
B[] TestArray = new B[3];
B b1 = new B();
C c1 = new C();
D d1 = new D();
TestArray[0] = b1;
TestArray[1] = c1;
TestArray[2] = d1;
for (int i = 0; i < TestArray.Length; i++)
{
TestArray[i].MethodOne();
}
Console.ReadLine();
}
}
I did it in this code in this link
http://www.4shared.com/rar/0SG0Rklxce/OverridingMoeThanOnce.html
Method overriding is OOP feature that allows a child class to provide a specific implementation of a method that is already provided by one of its parent classes.