I have a Base class and 2 derived classes. I have a variable of base class which can hold one of the derived classes. I want to send that variable to a method which receives derived classes.
What can I do to resolve this problem without explicit cast since I don't know what the variable holds?
code:
Class A{
virtual public void foo1() {/.../}
}
Class B : A{
override public void foo1() {/.../}
}
Class C : A{
override public void foo1() {/.../}
}
Class D{
public foo(B argB) {/.../}
public foo(C argC) {/.../}
// in main
D varD = new D();
A varA = new B();
varD.foo(varA); //--->> Problem here need explicit casting
A varC = new C();
varD.foo(varC); //--->> Problem here need explicit casting
I don't know what derived class I'm sending to varD.foo and I want different handling of different derived classes. What can I do?
This is not what polymorphism is about - you can not pass a base class where a specialized class is expected, even when explicitly casting. Polymorphism works the other way: You can pass a specialized class wherever the base class is expected.
What you should do is make D.foo expect A and you will automatically be fine. If you add any methods to B or C which have no base implementation in A, you need to pass B anyway and can not cast an A to B or D.
Just make foo an abstract instance method of A and override the implementation in B and C. You could even keep your class D and delegate the actual work to there but it depends if this is a good idea.
Here the code with delegation to D. Also note that I omitted the method foo1() in all classes.
public abstract class A
{
public abstract void foo(D d);
}
public sealed class B : A
{
public override void foo(D d)
{
d.foo(this);
}
}
public sealed class C : A
{
public override void foo(D d)
{
d.foo(this);
}
}
public sealed class D
{
public void foo(B b) { [...] }
public void foo(C c) { [...] }
}
Now you can use virtual method dispatching to call the correct method.
D d = new D();
A b = new B();
A c = new C();
b.foo(d); // Calls B.foo(D) and in turn D.foo(B).
c.foo(d); // Calls C.foo(D) and in turn D.foo(C).
Related
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.
This is my problem:
I have a Class A that is used (instantiated) several times within a Class B.
I need to change the behaviour of the Class A, mainly the constructor, and then I derived it with Class C.
Class C: Class A
I would like that Class B using in its methods Class C instead of Class A, avoiding to override all the methods that used it.
Is it this possible?
Many thanks
I was not clear, therefore let me try to explain better with code.
Public Class A
{
`// Simple constructor
public A(params[])
{
// things here
}
}
Public Class C : A
{
// Constructor doing different thing then base
public C(params[]): base(params[])
{
// do different things here
}
}
Public class B
{
public B(params[])
{ }
public method_A(params[])
{
A _temp = new A(params[]);
// do things here with A
}
}
I use B in my program, but I would like that for one istance of B it uses A and for another instance of B it uses C instead of A.
Something like:
Main()
{
B _instance1 = new B();
B _instance2 = new B();
// use instance 1
_instance1.method_A(...);
// use instance 2
_instance2.method_A(...); // do something here for using C instead of A in the method
}
Just instantiate class C in class B and use it as you would class A, it will have the same functions as A with your added logic in class C.
in your constructor it might be worthwhile to do something like:
public class C : A
{
public C() : base()
{
// do stuff
}
}
so that it will also call A's constructor.
I have a generic type G<T> where T : A, where A is an abstract class. In each class B derived from A I want to have a field of type G<B>, without writing repetetive code, however I'm not sure if it's even possible. One way to do this would be
abstract class A
{
protected object g;
protected abstract void SetG();
public A()
{
SetG();
}
}
class B : A
{
protected override void SetG()
{
this.g = new G<B>();
}
public B() : base() {}
}
But this would mean a lot of repetetive code in every derived class. Is there a better way to do this?
You could add an extra abstract class in between:
public abstract class A<T> : A where T : A
{
protected override void SetG()
{
this.g = new G<T>();
}
}
...then, update your B declaration to:
public class B : A<B>
{
public B() : base() { }
}
I believe that what you are trying to do is a Covariant Conversion. See this MSDN article on using delegates and see if that works for you. Look in the section "Using Delegates with Covariant Type Parameters".
In your A:, create a delegate:
Func<G<A>> GetG;
Then, in your derived classes, set this func pointer to a function of type
Func<G<B>>
Bingo!
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.
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.