H
H
hidden_pingvin2019-10-14 14:07:55
OOP
hidden_pingvin, 2019-10-14 14:07:55

Why does overriding in C# work like this?

//Пример 1:
  public class Class2 
    {
        public string GetValue(int a, int b)
        {
            return "base";
        }
    }

    public class Class3 : Class2
    {
        public string GetValue(int a, int b, bool becauseNeeded = true)
        {
            return "child";
        }
    }
  
  //...
  //вызов где-то в точке входа
  void Main()
  {
    string res = c.GetValue(1,2);
  }

In this example (Example 1), the base class method is overloaded, but when this method is called, the child class method is called. Shouldn't the base class method have been called since it wasn't an override?
If you do not use inheritance (Example 2), then the method that returns "base" is called.
//Пример 2:
  public class Class3 
    {
        public string GetValue(int a, int b)
        {
            return "base";
        }
        public string GetValue(int a, int b, bool becauseNeeded = true)
        {
            return "child";
        }
    }

Why does it work like this?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
V
Victor Bomberow, 2019-10-14
@hidden_pingvin

public class Class2
    {
        public string GetVal(int a, int b)
        {
            return "base";
        }

        public override string ToString()
        {
            return "_Class2_";
        }
    }

public class Class3 : Class2
    {

        
        public string GetVal(int a, int b, bool defaultpar = true)
        {
            return "child with bool";
        }

        public new string GetVal(int a, int b)
        {
            return "child";
        }

        public override string ToString()
        {
            return "_Class3_";
        }
    }

class Program
    {
        static void Main(string[] args)
        {
            Class2 obj_reference_c2 = new Class2();
            Class3 obj_reference_c3 = new Class3();
            Class2 obj_reference_assigned = obj_reference_c3;
            Class2 obj_reference_casted = (Class2)obj_reference_c3;

            Console.WriteLine($"Вызов - {obj_reference_c2} c параметрами 1, 2 : {obj_reference_c2.GetVal(1, 2)}");
            Console.WriteLine($"Вызов - {obj_reference_c3} c параметрами 1, 2 : {obj_reference_c3.GetVal(1, 2)}");
            Console.WriteLine($"Вызов {obj_reference_c3} c параметрами 1, 2 true: {obj_reference_c3.GetVal(1, 2, true)}");

            Console.WriteLine($"Вызов Class3 присвоенного по ссылке типа Class2 - {obj_reference_assigned} c параметрами 1, 2: {obj_reference_assigned.GetVal(1, 2)}");
            Console.WriteLine($"Вызов Class3 приведенного к типу Class2 - {obj_reference_casted} c параметрами 1, 2: {obj_reference_casted.GetVal(1, 2)}");

            /*      
            Вариант 1: в Class3 метод public string GetVal(int a, int b) {return "child";} закомментирован

                Вызов - _Class2_ c параметрами 1, 2 : base
                Вызов - _Class3_ c параметрами 1, 2 : child with bool
                Вызов _Class3_ c параметрами 1, 2 true: child with bool
                Вызов Class3 присвоенного по ссылке типа Class2 - _Class3_ c параметрами 1, 2: base
                Вызов Class3 приведенного к типу Class2 - _Class3_ c параметрами 1, 2: base

             */

            /*
              Вариант 2: в Class3 метод public string GetVal(int a, int b) {return "child";} существует и прячет унаследованный член Class2.GetVal(int,int)
            
                Вызов - _Class2_ c параметрами 1, 2 : base
                Вызов - _Class3_ c параметрами 1, 2 : child
                Вызов _Class3_ c параметрами 1, 2 true: child with bool
                Вызов Class3 присвоенного по ссылке типа Class2 - _Class3_ c параметрами 1, 2: base
                Вызов Class3 приведенного к типу Class2 - _Class3_ c параметрами 1, 2: base

                в подобном случае требуется явно указывать в объявлении модификатор new:
                   public new string GetVal(int a, int b) {return "child";}
             */
            Console.ReadLine();
        }
    }

In your example 1, there is no base class method overloading.
The base class method can be overridden ( public new string Foo() ) or overridden if the base method is virtual.
Overloaded methods exist in only one scope, which in C# is limited to classes.
From the point of view of .Net, methods with signatures string _ (int, int) and string _ (int, int, bool) are different, but syntactically, if in the method string _ (int, int, bool) the third parameter is supplied with a parameter by default, there is no explicit way to call other than Named Arguments .
public class Class2
    {
        public string GetVal(int a, int b)
        {
            return "base";
        }

        public override string ToString()
        {
            return "_Class2_";
        }
    }

    public class Class3 : Class2
    {
        public new string GetVal(int a, int b)
        {
            return "child";
        }

        public string GetVal(int A, int B, bool defaultpar = true)
        {
            return "child with bool";
        }

        public override string ToString()
        {
            return "_Class3_";
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Class2 obj_reference_c2 = new Class2();
            Class3 obj_reference_c3 = new Class3();
            Class2 obj_reference_assigned = obj_reference_c3;
            Class2 obj_reference_casted = (Class2)obj_reference_c3;

            Console.WriteLine($"Вызов - {obj_reference_c2} c параметрами 1, 2 : {obj_reference_c2.GetVal(1, 2)}");
            Console.WriteLine($"Вызов - {obj_reference_c3} c параметрами 1, 2 : {obj_reference_c3.GetVal(1, 2)}");
            Console.WriteLine($"Вызов - {obj_reference_c3} c параметрами 1, 2 : {obj_reference_c3.GetVal(A:1, B:2)}");
            Console.WriteLine($"Вызов {obj_reference_c3} c параметрами 1, 2 true: {obj_reference_c3.GetVal(1, 2, true)}");

            Console.WriteLine($"Вызов Class3 присвоенного по ссылке типа Class2 - {obj_reference_assigned} c параметрами 1, 2: {obj_reference_assigned.GetVal(1, 2)}");
            Console.WriteLine($"Вызов Class3 приведенного к типу Class2 - {obj_reference_casted} c параметрами 1, 2: {obj_reference_casted.GetVal(1, 2)}");

            /*
               
            Вариант 1Б: в Class3 метод public string GetVal(int a, int b) {return "child";} закомментирован

                Вызов - _Class2_ c параметрами 1, 2 : base
                Вызов - _Class3_ c параметрами 1, 2 : child with bool
                Вызов - _Class3_ c параметрами 1, 2 : child with bool
                Вызов _Class3_ c параметрами 1, 2 true: child with bool
                Вызов Class3 присвоенного по ссылке типа Class2 - _Class3_ c параметрами 1, 2: base
                Вызов Class3 приведенного к типу Class2 - _Class3_ c параметрами 1, 2: base

             */

            /*

           Вариант 2Б: в Class3 метод public string GetVal(int a, int b) {return "child";} существует и прячет базовый

                Вызов - _Class2_ c параметрами 1, 2 : base
                Вызов - _Class3_ c параметрами 1, 2 : child
                Вызов - _Class3_ c параметрами 1, 2 : child with bool
                Вызов _Class3_ c параметрами 1, 2 true: child with bool
                Вызов Class3 присвоенного по ссылке типа Class2 - _Class3_ c параметрами 1, 2: base
                Вызов Class3 приведенного к типу Class2 - _Class3_ c параметрами 1, 2: base

            */

            Console.ReadLine();
        }
    }

This example is not very indicative in terms of using named arguments.
This will require several arguments with default values.
While I recommend never using default values, instead make SOLID classes with specialized methods and a clear API, and named arguments allow you to write code frivolously out of the order of the arguments in the signature, even backwards: c.GetVal( defaultpar: false, B: 42, A: 777);

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question