Why is base class method called instead of derived class method? - c#

Expecting "Hello from the derived." but getting "Hello from the base.".
class Program
{
interface IBase
{
void Method();
}
public class Base: IBase
{
public virtual void Method()
{
Console.WriteLine("Hello from the base.");
}
}
public class Derived : Base
{
public virtual new void Method()
{
Console.WriteLine("Hello from the derived.");
}
}
static void Main(string[] args)
{
IBase x = new Derived();
x.Method();
}
}
So why isn't the derived class's method called. And more importantly, how can I get the derived classes method to get called without casting x to the Derived type?
In my actual application, IBase has several other related methods and Derived only replaces two of the methods in IBase.

When you use the new modifier you are specifically saying that the method is not part of the virtual dispatch chain for that hierarchy, so calling the method by the same name in the base class will not result in redirection to the child class. If you mark the method with override instead of new then you will see the virtual dispatch that you are expecting to see.
You will also need to remove virtual from the derived class's method as you cannot mark an override method as virtual (it already is).
If you really don't want to override the method then it may be more appropriate, in your situation, to not use inheritance at all. You may simply want to use interfaces exclusively:
public interface IFoo
{
void Foo();
}
public class A : IFoo
{
public void Foo()
{
Console.WriteLine("I am A, hear me roar!");
}
}
public class B : IFoo
{
public void Foo()
{
Console.WriteLine("I am B, hear me roar!");
}
}
private static void Main(string[] args)
{
IFoo foo = new A();
foo.Foo();
foo = new B();
foo.Foo();
Console.WriteLine();
Console.WriteLine("Press any key to exit . . .");
Console.ReadKey(true);
}

This is basic polymorphism at work.
For the behavior you're looking for, you would need to set your derived method to override the inherited method:
public class Derived : Base
{
public override void Method()
{
Console.WriteLine("Hello from the derived.");
}
}

Use the override keyword instead of virtual new in your child class.
Therefore, your code should look like:
class Program
{
interface IBase
{
void Method();
}
public class Base: IBase
{
public virtual void Method()
{
Console.WriteLine("Hello from the base.");
}
}
public class Derived : Base
{
public override void Method() // The magic happens here!
{
Console.WriteLine("Hello from the derived.");
}
}
static void Main(string[] args)
{
IBase x = new Derived();
x.Method();
}
}
As described here, the new keyword is used to hide the parent method, which is not what you're looking for.

new keyword creates a new method and says that the base method is hidden. But it is only for consumers of your derived class, since the base class code does not know anything about it.
override keyword overrides the base class implementation with a new one.
class Program
{
interface IBase
{
void Method();
}
public class Base: IBase
{
public virtual void Method()
{
Console.WriteLine("Hello from the base.");
}
}
public class Derived : Base
{
// the next line was changed.
public override void Method()
{
Console.WriteLine("Hello from the derived.");
// note that if you want to call the original implementation, you do it like this:
base.Method();
}
}
static void Main(string[] args)
{
Base x = new Derived();
x.Method();
}
}

The new'd Method in Derived only exists in a Derived instance, where it effectively hides the base implementation.
But IBase type only knows the Base's implementation, so it calls that.
To answer your question, to call the derived's implementation you'd do:
Derived d = new Derived();
d.Method();
((IBase)d).Method();
//Prints:
//Hello from the derived.
//Hello from the base.

Related

Why does this code not return the class instance from the interface? [duplicate]

This question already has answers here:
Can a C# class call an interface's default interface method from its own implementation?
(3 answers)
Closed 8 months ago.
When this code is run (I'm using .NET 6.0), it recurses infinitely, and never gets to DoSomething() in IInterface, instead of returning the Class instance from the interface.
It seems because of the return type of the method in the class being the same as in the interface, the compiler seems to think the interface's method is being reimplemented in the class, and the method calls itself.
If the method's return type is changed to the concrete class, it works without a problem. Why is it?
using System;
public class Program
{
public static void Main()
{
var obj = new Class();
var ret = obj.DoSomething();
Console.WriteLine("Finished");
}
}
interface IInterface {
IInterface DoSomething() {
return new Class();
}
}
class Class : IInterface {
// Infinite recursion
public IInterface DoSomething() => ((IInterface)this).DoSomething();
// Works
//public Class DoSomething() => (Class)((IInterface)this).DoSomething();
}
If you mark your interface method as sealed it will prevent recursion, but you won't be able to re-implement the method in another class
interface IInterface {
sealed IInterface DoSomething() {
return new Class();
}
}
class Class : IInterface {
public IInterface DoSomething() => ((IInterface)this).DoSomething();
}
Alternatively, you could make the class implementation private, and access it from another method. This will allow you to re-implement the interface in another class.
internal class Class : IInterface
{
private IInterface DoSomething() => ((IInterface)this).DoSomething();
public IInterface DoSomethingPublic() => DoSomething();
}
Unfortunately, there just isn't support for what you want to do currently. There was a section in the original Default Interface Methods proposal about the possibility of using base() to explicitly call an inherited interface, but that was cut.
I admit that I am not very familiar with default interface methods, but I suspect that the default behavior is to override the implementation, and by marking the interface as sealed you prevent this from happening.
If someone has a better explanation, please correct me!
Some reading material:
Default Interface Methods Proposal
A similar question with hacky workarounds
A. Base class
Classic base class implementation:
class BaseClass {
protected void DoSomething() {
Console.WriteLine("Hello from BaseClass!");
}
}
class Class : BaseClass {
public new void DoSomething() // new or virtual + override
{
Console.WriteLine("Hello from Class");
base.DoSomething();
}
}
B. Helper method
static class Helper {
public static void DoSomething() => Console.WriteLine("Do something!");
}
interface IInterface {
void DoSomething() => Helper.DoSomething();
}
class Class : IInterface {
public void DoSomething() { Console.WriteLine("Hello from Class"); Helper.DoSomething();}
}
C. Static interface method
I would say that this seems to be a case for a base class not an interface, but one way to 'reuse' the interface method is to make the interface method static.
For example:
var obj = new Class();
obj.DoSomething();
Console.WriteLine("Finished");
interface IInterface {
static void DoSomething() {
Console.WriteLine("Hello from IInterface!");
}
}
class Class : IInterface {
public void DoSomething() { Console.WriteLine("Hello from Class"); IInterface.DoSomething();}
}
This prints:
Hello from Class
Hello from IInterface!
Finished

C# polymorphism - upcasting

I would like to ask you for an explanation of this example:
public class A : B
{
public override void Method()
{
Console.WriteLine("A");
}
}
public class B
{
public virtual void Method()
{
Console.WriteLine("B");
}
}
Equation:
void Main()
{
B b = (B)new A();
b.Method(); // result A
}
Why upcasting did not work in this case?
How microsoft docs say:
If you want your derived class to have a member with the same name as a member in a base class, you can use the new keyword to hide the base class member. The new keyword is put before the return type of a class member that is being replaced. The following code provides an example:

Call a virtual method from its overridden

In order to call the base virtual method from its overridden one, how should I define the instance?
Assume I have class Derived which extends Base class. I have a virtual method in Base which is overrided in class Derived.
Like this : Base instance = new Derived();
or like this: Derived instance = new Derived();
For sure I shall not use Base instance = new Based(); for it call the virtual methos and not its override.
Whether a method override calls the implementation of the base class does not depend on the type of variable you use. So, as soon as you add base.MethodName() to the implementation of the override, the first two ways you describe will be ok.
As you also mention, the third approach will not work as it does not call the overridden version of the method.
Here is a grotty way you can do that. You'll have to expose a method which calls base version. IMO don't do that. but... It is possible.
void Main()
{
B b = new B();
b.DoSomething();
b.CallAVersionDoSomething();
}
class A
{
public virtual void DoSomething()
{
Console.WriteLine("A DoSomething");
}
}
class B : A
{
public override void DoSomething()
{
Console.WriteLine("B DoSomething");
}
public virtual void CallAVersionDoSomething()
{
base.DoSomething();
}
}
Or if you want to expose it really you can expose another method in Base class which does the job for you. Here's how you go
class A
{
public virtual void DoSomething()
{
ActualDoSomething();
}
public void ActualDoSomething()
{
Console.WriteLine("A DoSomething");
}
}
class B : A
{
public override void DoSomething()
{
Console.WriteLine("B DoSomething");
}
}
and you can use instance.ActualDoSomething() which can't be overridden so you get base class version all the time.

Why does Java and C# differ in oops?

1) Why does the following codes differ.
C#:
class Base
{
public void foo()
{
System.Console.WriteLine("base");
}
}
class Derived : Base
{
static void Main(string[] args)
{
Base b = new Base();
b.foo();
b = new Derived();
b.foo();
}
public new void foo()
{
System.Console.WriteLine("derived");
}
}
Java:
class Base {
public void foo() {
System.out.println("Base");
}
}
class Derived extends Base {
public void foo() {
System.out.println("Derived");
}
public static void main(String []s) {
Base b = new Base();
b.foo();
b = new Derived();
b.foo();
}
}
2) When migrating from one language to another what are the things we need to ensure for smooth transition.
The reason is that in Java, methods are virtual by default. In C#, virtual methods must explicitly be marked as such.
The following C# code is equivalent to the Java code - note the use of virtual in the base class and override in the derived class:
class Base
{
public virtual void foo()
{
System.Console.WriteLine("base");
}
}
class Derived
: Base
{
static void Main(string[] args)
{
Base b = new Base();
b.foo();
b = new Derived();
b.foo();
}
public override void foo()
{
System.Console.WriteLine("derived");
}
}
The C# code you posted hides the method foo in the class Derived. This is something you normally don't want to do, because it will cause problems with inheritance.
Using the classes you posted, the following code will output different things, although it's always the same instance:
Base b = new Derived();
b.foo(); // writes "base"
((Derived)b).foo(); // writes "derived"
The fixed code I provided above will output "derived" in both cases.
The C# code will compile with warnings, since you are hiding methods there.
In Java, class-methods are always virtual, whereas in C# they're not, and you have to mark them explicitly as 'virtual'.
In C#, you'll have to do this:
public class Base
{
public virtual void Foo()
{
Console.WriteLine ("Base");
}
}
public class Derived : Base
{
public override void Foo()
{
Console.WriteLine ("Derived.");
}
}

Is there a way to hide the methods partially in child classes?

This question seems weird, but i came across this question in one of the interviews recently.
I ve been asked, is there a way in c# to hide the methods partially in a inherited child classes?. Assume the base class A, exposed 4 methods. Class B implements A and it will only have the access to first 2 methods and Class C implements A will only have the access to last 2 methods.
I know we can do this way
public interface IFirstOne
{
void method1();
void method2();
}
public interface ISecondOne
{
void method3();
void method4();
}
class baseClass : IFirstOne, ISecondOne
{
#region IFirstOne Members
public void method1()
{
throw new NotImplementedException();
}
public void method2()
{
throw new NotImplementedException();
}
#endregion
#region ISecondOne Members
public void method3()
{
throw new NotImplementedException();
}
public void method4()
{
throw new NotImplementedException();
}
#endregion
}
class firstChild<T> where T : IFirstOne, new()
{
public void DoTest()
{
T objt = new T();
objt.method1();
objt.method2();
}
}
class secondChild<T> where T : ISecondOne, new()
{
public void DoTest()
{
T objt = new T();
objt.method3();
objt.method4();
}
}
But what they wanted is different. They wanted to hide these classes on inheriting from baseclasses. something like this
class baseClass : IFirstOne, ISecondOne
{
#region IFirstOne Members
baseClass()
{
}
public void method1()
{
throw new NotImplementedException();
}
public void method2()
{
throw new NotImplementedException();
}
#endregion
#region ISecondOne Members
public void method3()
{
throw new NotImplementedException();
}
public void method4()
{
throw new NotImplementedException();
}
#endregion
}
class firstChild : baseClass.IFirstOne //I know this syntax is weird, but something similar in the functionality
{
public void DoTest()
{
method1();
method2();
}
}
class secondChild : baseClass.ISecondOne
{
public void DoTest()
{
method3();
method4();
}
}
is there a way in c# we can achieve something like this...
I did it by having 1 main base class and 2 sub bases.
// Start with Base class of all methods
public class MyBase
{
protected void Method1()
{
}
protected void Method2()
{
}
protected void Method3()
{
}
protected void Method4()
{
}
}
// Create a A base class only exposing the methods that are allowed to the A class
public class MyBaseA : MyBase
{
public new void Method1()
{
base.Method1();
}
public new void Method2()
{
base.Method2();
}
}
// Create a A base class only exposing the methods that are allowed to the B class
public class MyBaseB : MyBase
{
public new void Method3()
{
base.Method3();
}
public new void Method4()
{
base.Method4();
}
}
// Create classes A and B
public class A : MyBaseA {}
public class B : MyBaseB {}
public class MyClass
{
void Test()
{
A a = new A();
// No access to Method 3 or 4
a.Method1();
a.Method2();
B b = new B();
// No Access to 1 or 2
b.Method3();
b.Method4();
}
}
Although you can't do exactly what you want, you could use explicit interface implementation to help, in which the interface members are only exposed if it is explicitly cast to that interface...
Perhaps the interviewer may have been referring to method hiding?
This is where you declare a method with the same signature as on in your base class - but you do not use the override keyword (either because you don't or you can't - as when the method in the base class is non-virtual).
Method hiding, as opposed to overriding, allows you to define a completely different method - one that is only callable through a reference to the derived class. If called through a reference to the base class you will call the original method on the base class.
Don't use inheritance. It makes the public or protected facilities of the base class available directly in the derived class, so it simply isn't want you want.
Instead, make the derived class implement the relevant interface, and (if necessary) forward the methods on to a private instance of the underlying class. That is, use composition (or "aggregation") instead of inheritance to extend the original class.
class firstChild : IFirstOne
{
private baseClass _owned = new baseClass();
public void method1() { _owned.method1(); }
// etc.
}
By the way, class names should start with an upper case letter.
There is 2 solutions to hide methods inherited from a base class:
As mentioned by thecoop, you can explicitely implement the interface declaring the methods you want to hide.
Or you can simply create these methods in the base class (not inherited from any interface) and mark them as private.
Regards.
What about injecting base class as an IFirst?
interface IFirst {
void method1();
void method2();
}
interface ISecond {
void method3();
void method4();
}
abstract class Base : IFirst, ISecond {
public abstract void method1();
public abstract void method2();
public abstract void method3();
public abstract void method4();
}
class FirstChild : IFirst {
private readonly IFirst _first;
public FirstChild(IFirst first) {
_first = first;
}
public void method1() { _first.method1(); }
public void method2() { _first.method2(); }
}
Injection keeps you from violating the Interface Segregation Principle. Pure inheritance means that your FirstChild is depending on an interface that it doesn't use. If you want to retain only the IFirst functionality in Base, but ignore the rest of it, then you cannot purely inherit from Base.

Categories