C# class polymorphism - c#

Why the result of the fallowing code is:
Class A
Class A
Class A
public class A {
public virtual void f() {
Console.WriteLine("Class A");
}
}
public class B : A {
public virtual void f() {
Console.WriteLine("Class B");
}
}
public class C : B {
public override void f() {
Console.WriteLine("Class C");
}
}
//...
static void Main(string[] args) {
A[] array = new A[3];
array[0] = new A();
array[1] = new B();
array[2] = new C();
for(int d = 0; d < 3; d++)
array[d].f();
}

It's because virtual does not equals to override. By using virtual keyword you essentially creating new method, which is virtual but it is new to your class(class B) and does not override class's A method. Class C which is inherited from B doesn't know about class's A method f() so it takes B.f() to override it. And in the Main method you are creating an array of A classes where only A.f() method exists.
If you want
Class A
Class B
Class C
output use override instead of virtual in class B.

AAA because
A[] array = new A[3]; /*main reference to A object*/

Related

why need to use virtual and override?

i have created same name methods in base and derived classes and i am able to create
class Program
{
public void CalculateArea(int a,int b)
{
Console.WriteLine(a*b);
}
}
class progrmm1:Program
{
public void CalculateArea(int a ,int b)
{
Console.WriteLine(a + b);
}
static void Main(string[] args)
{
progrmm1 obj = new progrmm1();
Program obj1 = new Program();
obj.CalculateArea(4,5);
obj1.CalculateArea(4,5);
Console.ReadLine();
}
}
then why i need to use virtual and override
If you don't use virtual and override then you are not taking advantage of polymorphism. Basically the CalculateArea in the derived class is hiding the one in the base class. That means that if you reference an object of the derived class type as the base it will call the CalculateArea in the base class instead of the derived one. Where as if you use virtual and override it would call the Derived method even if it where referenced as the Base.
For example with these classes
public class Base
{
public void DoSomething()
{
Console.WriteLine("Base.DoSomething");
}
}
public class Derived : Base
{
public void DoSomething()
{
Console.WriteLine("Derived.DoSomething");
}
}
This code
Base derivedAsBase = new Derived();
derivedAsBase.DoSomething();
will output
Base.DoSomething
but using virtual and override
public class Base
{
public virtual void DoSomething()
{
Console.WriteLine("Base.DoSomething");
}
}
public class Derived : Base
{
public override void DoSomething()
{
Console.WriteLine("Derived.DoSomething");
}
}
The same code
Base derivedAsBase = new Derived();
derivedAsBase.DoSomething();
will output
Derived.DoSomething
When overridden, the method on the most derived class is called. Observe this slightly modified code where I assign two Program instances. One from a Program and one from a program1:
class Program
{
public virtual void CalculateArea(int a, int b)
{
Console.WriteLine(a * b);
}
}
class progrmm1 : Program
{
public override void CalculateArea(int a, int b)
{
Console.WriteLine(a + b);
}
static void Main(string[] args)
{
Program obj = new progrmm1();
Program obj1 = new Program();
obj.CalculateArea(4, 5);
obj1.CalculateArea(4, 5);
Console.ReadLine();
}
}
OUTPUT:
9
20
And now, observe non-virtual:
class Program
{
public void CalculateArea(int a, int b)
{
Console.WriteLine(a * b);
}
}
class progrmm1 : Program
{
public void CalculateArea(int a, int b)
{
Console.WriteLine(a + b);
}
static void Main(string[] args)
{
Program obj = new progrmm1();
Program obj1 = new Program();
obj.CalculateArea(4, 5);
obj1.CalculateArea(4, 5);
Console.ReadLine();
}
}
OUTPUT
20
20
First you need to know about Virtual Method.
Basically A virtual method is a method that can be redefined in
derived classes. A virtual method has an implementation in a base
class as well as derived the class.
Example:
Let Suppose we have two classes, A and B. Class A has a public virtual method called Test. Class B, meanwhile, derives from class A and it provides a public override method called Test as well.
using System;
class A
{
public virtual void Test()
{
Console.WriteLine("A.Test");
}
}
class B : A
{
public override void Test()
{
Console.WriteLine("B.Test");
}
}
class Program
{
static void Main()
{
// Compile-time type is A.
// Runtime type is A as well.
A ref1 = new A();
ref1.Test();
// Compile-time type is A.
// Runtime type is B.
A ref2 = new B();
ref2.Test();
}
}
Output
A.Test
B.Test
Why would you need to use virtual methods?:
Your program may be designed in such a way that you do not know all the types of objects that will occur when it is executed. You can provide a standard (base) type and design around that type.
Then, you can re-implement important functionality depending on the more specific (derived) types. When you call a method on the base type, you invoke the more derived (and useful) method.

How inheritance will work with different class objects

Here is an Inheritance question. I was trying to understand TAG1 to TAG3 Process. what exactly going happen and hold which class reference. Looking forward to your suggestion.
static void Main(string[] args)
{
B b = new B(); **// What Happens here TAG1**
A a = b; **//What Happens here TAG2**
B x = new A() as B; **//what happens here TAG3**
a.F();
a.G();
a.H();
a.Z();
b.F();
b.G();
b.H();
b.Z();
x.F();
Console.ReadLine();
}
public class A
{
public void F() { Console.WriteLine("A.F"); }
public virtual void G() { Console.WriteLine("A.G"); }
public virtual void H() { Console.WriteLine("A.H"); }
public void Z() { Console.WriteLine("A.Z"); }
}
public class B : A
{
new public void F() { Console.WriteLine("B.F"); }
public override void G() { Console.WriteLine("B.G"); }
new public void H() { Console.WriteLine("B.H"); }
}
B b = new B(); **// What Happens here TAG1**
An instance of B is created here, and b holds a reference to it.
A a = b; **//What Happens here TAG2**
a is assigned that b instance, which means you can access the A part of the previously crated B object.
B x = new A() as B; **//what happens here TAG3**
You create an A object and cast it to B, but the cast is gonna fail and return null. Therefore x will not reference the instance of an object.

C# Access a method from one class, and not another

and sorry in advance if this question has been solved previously.
I am creating a small library in C# and am hoping to have class A be able to modify the data members of class B, where class A and B exist in the same namespace, C.D. This is not a problem to accomplish though I would like class E, in namespace C, to not be able to access the data members of B.
namespace C.D
{
class B
{
modifier int
a,
b;
public B()
{
}
}
class A
{
public A() {}
public B DoStuff()
{
B b = new B();
b.a = 1; b.b = 2;
return b;
}
}
}
namespace C
{
class E
{
static void Main(String[] args)
{
A a = new A();
B b = a.DoStuff();
}
}
}
In my main method above I would like every class in the namespace C.D to be able to alter the data members of a class B object though nothing outside of the C.D namespace to be able to modify class B object data members.
Is there any way to do this by changing the namespace structure, modifiers, or implementing specific design patterns?
Thank you all in advance. : )
You can use the "internal" access modifier if you're willing to move the relevant classes in C.D to a separate assembly.
namespace C.D
{
class B
{
internal int a;
internal int b;
public B()
{
}
}
}
One way to achieve this is by:
Moving Class A's definition into Class B (nesting it within class B { ... })
Making Class B's fields (a and b) private.
i.e.
namespace C.D
{
class B
{
private int a, b;
public B()
{
}
class A
{
public A() { }
public B DoStuff()
{
B b = new B();
b.a = 1; b.b = 2;
return b;
}
}
}
}
namespace C
{
class E
{
static void Main(String[] args)
{
A a = new A();
B b = a.DoStuff();
}
}
}
Another way to achieve this is to make Class B's fields protected, then make all classes that should have access to Class B's fields derive from Class B. This way you won't need to nest Class A inside Class B. i.e.
namespace C.D
{
class B
{
protected int a, b;
public B()
{
}
}
class A : B
{
public A() {}
public B DoStuff()
{
B b = new B();
b.a = 1; b.b = 2;
return b;
}
}
}
namespace C
{
class E
{
static void Main(String[] args)
{
A a = new A();
B b = a.DoStuff();
}
}
}

Class nesting and access modifiers

I have following piece of code:
class A
{
public C GetC()
{
return new C();
}
}
class B
{
//has access to A but can not create C. Must ask A to create C.
private void method()
{
A a = new A();
C c = a.GetC();//Ok!
C c2 = new C();//Not allowed.
}
}
class C
{
}
What access modifiers should be used on C so it is ONLY accessible through A? (only class A knows how to properly initialize class C)
Or is there a better solution?
If you make A a nested class in C it should work.
public class B
{
//has access to A but can not create C. Must ask A to create C.
private void method()
{
var a = new C.A();
var c = a.GetC();//Ok!
var c2 = new C();//Not allowed.
}
}
public class C
{
private C()
{
}
public class A
{
public C GetC()
{
return new C();
}
}
}
Inherit A from C, and make Constructor of C protected
EDIT -- "as protected member cannot be accessed via qualifier ", error is coming, as a work around, static member is introduced which will return the instance. This protected member is accessible from derived.
class A : C
{
private C GetC()
{
C c = C.GetC();
return c;
}
}
class C
{
protected C()
{
}
protected static C GetC()
{
return new C();
}
}
Proposed method Inherit A from C, and make Constructor of C protected code doesn't work because in it are some errors. Adjusted this method code is below:
class B
{
static void Main(string[] args)
{
A a = new A();
C c = a.GetC();
C c2 = C(); //Non-invocable member 'C' cannot be used like a method
}
}
class A : C
{
public new C GetC()
{
C c = C.GetC();
return c;
}
}
class C
{
protected C()
{
}
protected static C GetC()
{
return new C();
}
}

OpCodes.Castclass. Is it necessary?

Is it necessary to emit OpCode.CastClass(typeof(A)) when you having a reference to instance of (B) on top of stack, where B is class, derived from A, when preparing for a call to method with argument of type A?
Addition:
interface IFoo
{
void IFoo();
}
public class A:IFoo
{
public void IFoo()
{
}
}
public class B:A,IFoo
{
new public void IFoo()
{
}
}
var b = new B();
(b as IFoo).Foo();
((b as A) as IFoo).Foo();
I guess you have something like this:
class A
{
public void Foo() { }
}
class B : A
{
}
and need to decide between:
B b = new B();
b.Foo();
and
B b = new B();
((A)b).Foo();
Both work. But the cast is not necessary, because B inherits all members from A.

Categories