OOP方法隐藏和重载

huangapple go评论64阅读模式
英文:

OOP Method hidden and overloaded

问题

  1. 您的描述大致是正确的。对于第一个调用,变量 x1 的类型由编译器从表达式的右侧推断,因此类型为 C,所以显示 "C"。对于第二个调用,CLR(Common Language Runtime)会确定对象的实际类型是 C,并调用相应的虚拟方法重载,因此也会显示 "C"。在第三种情况下,由于 B.Print 方法的声明隐藏了 A.Print 方法,CLR 不认为 B.Print 和 C.Print 是重载,因此调用类 A 的方法,显示 "A"。

  2. 对于 Habr 上的解释,它在大多数情况下是准确的。然而,有些地方可能需要更清晰的表达或补充说明,特别是在解释 CLR 如何处理不同类型的变量时。不过总体而言,这篇解释对于理解这个示例非常有帮助。

英文:

I'm new to programming. I study books. Sometimes some examples raise questions. I ask for help, the explanation on the Habr is not very clear.
Found an example [on a habr] [1] - the fourth question on C#.

class Program
    {
        static void Main(string[] args)
        {
            var x1 = new C(); 
            x1.Print(); //C

            B x2 = new C(); 
            x2.Print(); //C

            A x3 = new C(); 
            x3.Print(); //A
        }
    }



    class A
    {
        public void Print()
        {
            Console.WriteLine("A");
        }
    }

    class B : A
    {
        new public virtual void Print()
        {
            Console.WriteLine("B");
        }
    }

    class C : B
    {
        override public void Print()
        {
            Console.WriteLine("C");
        }
    }

Explained as follows:
In the first call, “C” will be displayed, since for var the compiler will infer the type of the object from the right side of the expression, and this will be type C. // Everything is clear with that.

For the second call, the value “C” will also be displayed, since the CLR will determine that the actual type of the object is C, and will invoke the necessary virtual method overload. //So...

//Further a little incomprehensible
In the third case, “A” will be displayed, since the declaration of the B.Print method (and hence its overloading in C) hides the A.Print method. Accordingly, the CLR does not consider B.Print and C.Print to be overloads and calls a class A method.

I’m already trying to describe step by step what is happening in the context of the stack and the heap:

x2:

  • on the heap memory is allocated for an instance of class C;
  • default constructor writes an instance of class C to this section;
  • a link to this piece of memory is written to the variable x2 (type B) on the stack, this is possible because B is the base class for C;
  • Next, you need to decide which Print method of all Print methods will be called and why.
    The CLR looks at the type of the variable and tries to call the method by type, that is, in the case of x2 it is B.Print (), but since the link we have is an instance of class C, and for it there is overload of this method, then C.Print () method is called;

x3:

  • on the heap memory is allocated for an instance of class C;
  • default constructor writes an instance of class C to this section;
  • a link to this piece of memory is written to the variable x3 (type A) on the stack, this is possible because A is the base class for B, B is the base class for C;
  • Next, you need to decide which Print method of all Print methods will be called and why.
    The CLR looks at the type of the variable and tries to call the method by type, that is, in the case of x3 it is A.Print (), but since the link we have is an instance of class C, and for it there is no overload of this method, then A.Print () method is called.
  1. Is my description true? If not, please explain with this example how it works.

  2. Do you fully agree with the explanation of the answer on the Habr or would you remove / add / replace something?
    [1]: https://habr.com/ru/article/474182/

答案1

得分: 1

在类B中,在print函数声明中写入了'new'关键字,这会破坏A和C之间的print函数的继承连接。

英文:

As in class B is written 'new' keyword in print function declaration, its brokes the inheritance connection between A and C print functions.

答案2

得分: 0

是的,根据它的工作方式和链接,我的解释是正确的。

运行时(而不是编译器)根据由此变量引用的对象的真实类型来调用方法的版本,当通过变量调用它时。(MS Visual C# Step by Step 9ed, CHAPTER 12 Working with inheritance)

https://stackoverflow.com/questions/59541044/why-is-dynamic-binding-not-working-the-way-i-expect-it-to-in-the-following-code

https://stackoverflow.com/questions/45872841/will-clr-check-the-whole-inheritance-chain-to-determine-which-virtual-method-to

英文:

Yes, judging by how it works and the links, my explanation is correct.

The runtime (not the compiler) works out which version of method to call when invoking it through a variable, based on the real type of the object referenced by this variable. (MS Visual C# Step by Step 9ed, CHAPTER 12
Working with inheritance)

https://stackoverflow.com/questions/59541044/why-is-dynamic-binding-not-working-the-way-i-expect-it-to-in-the-following-code

https://stackoverflow.com/questions/45872841/will-clr-check-the-whole-inheritance-chain-to-determine-which-virtual-method-to

huangapple
  • 本文由 发表于 2020年1月3日 17:45:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/59576251.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定