3

This is based on another SO question about polymophism which I liked very much. So I played around with it and modified it to understand it. But then it rattled my understanding of ploymorphism.

I created an interface inside of a class, created a class "A," and implemented the interface method. I also created another class "B" that extends "A." And another class "C" that extends "B."

When you run it, the output is:

BA-> AEP

Notice that BA-> part comes from B : A class while AEP is the default param from different method in A : E

How is it that two methods are called when I'm doing

`A instance = new C();
Console.WriteLine(instance.GetName());`

Why?

    class Program
{
    interface E
    {
        string GetName(string s);

    }

    public class A : E
    {

        public virtual string GetName(string s="AEP")
        {
            return s;
        }
    }

    public class B : A
    {
        public override string GetName(string s="BAP")
        {
            return "BA-> " + s;
        }
    }

    public class C : B
    {
        public new string GetName()
        {
            return "CB->";
        }
    }

    static void Main()
    {
        A instance = new C();
        Console.WriteLine(instance.GetName());
        Console.ReadLine();
    }
}
Zuzlx
  • 1,246
  • 14
  • 33
  • Change `return s` to `return s + "bla"` and you'll see it's just the default params – adjan Jun 24 '14 at 18:05
  • This is essentially duplicate of 2 questions - one [C# optional parameters on overridden methods](http://stackoverflow.com/questions/8909811/c-sharp-optional-parameters-on-overridden-methods) covers why "AEP" is shown and [C# keyword usage virtual+override vs. new](http://stackoverflow.com/questions/159978/c-sharp-keyword-usage-virtualoverride-vs-new) which explains why `C.GetName` is not called at all (and hence "BA->" part of output). Please comment if these links are not enough to clarify the issue. – Alexei Levenkov Jun 24 '14 at 18:13
  • @Zuzlx Because you never use `B` in your `Main`. – adjan Jun 24 '14 at 18:20

2 Answers2

4

The method is not called twice. What you're seeing is that the overridden version from B is called, because the run-time instance is C. However, because the static type is A you're using the default argument value for the method as defined by A. Default arguments are a compile time feature inserted at the call site, so it doesn't take the value of the overridden method into account.

Brian Rasmussen
  • 114,645
  • 34
  • 221
  • 317
0

You are using default parameters here, which is pure syntax sugar and resolved at compile time based on class methods you are using.

    A instance = new C();
    Console.WriteLine(instance.GetName());

As there's no GetName() method without parameters, compiler uses default parameter value and compiles it using declaration in class A (variable as it is known at compile time) as GetName("AEP").

Lanorkin
  • 7,310
  • 2
  • 42
  • 60