当我们可以直接创建ClassA对象并调用ClassA的printA方法时,如果有意隐藏,为什么需要使用new关键字?

本文关键字:ClassA 为什么 隐藏 如果 关键字 new 方法 我们 创建 对象 printA | 更新日期: 2023-09-27 17:54:05

当我们可以直接创建ClassA对象并调用ClassA的printA方法时,如果有意隐藏,为什么我们需要使用new

我很困惑,当我们有选项直接创建类对象并调用所需的方法时,为什么我们需要这个新关键字:

                class Program
                    {
                        static void Main()
                        {
                            classA clsA = new ClassB();
                            clsA.printA();
                        }
                    }
                    public class classA
                    {
                        public classA()
                        {
                            Console.WriteLine("ClassA constructor");
                        }
                        public void printA()
                        {
                            Console.WriteLine("ClassA-PrintA Method");
                        }
                    }
                    class ClassB : classA
                    {
                        public ClassB()
                        {
                            Console.WriteLine("ClassB constructor");
                        }
                        public void printB()
                        {
                            Console.WriteLine("ClassB-PrintB Method");
                        }
                        public new void printA()
                        {
                            Console.WriteLine("Class B extending ClassA.PrintA Method");
                        }       
                  } 

在这两种情况下,我们都必须调用类A的PrintA方法。

1)使用新的关键字与基地和派生类中的方法 ------------------------------------------------------------------

    class Program
                {
                    static void Main()
                    {
                        classA clsA = new classA();
                        clsA.printA();
                    }
                }
                public class classA
                {
                    public classA()
                    {
                        Console.WriteLine("ClassA constructor");
                    }
                    public virtual void printA()
                    {
                        Console.WriteLine("ClassA-PrintA Method");
                    }
                }
                class ClassB : classA
                {
                    public ClassB()
                    {
                        Console.WriteLine("ClassB constructor");
                    }
                    public new void printA()
                    {
                        Console.WriteLine("Class B extending ClassA.PrintA Method");
                    }
                }

2)没有使用新的关键字,不要在ClassB实现 ----------------------------------------------------------------
类项目{Main(){classA clsA = new classA();clsA.printA ();}}

                public class classA
                {
                    public classA()
                    {
                        Console.WriteLine("ClassA constructor");
                    }
                    public void printA()
                    {
                        Console.WriteLine("ClassA-PrintA Method");
                    }
                }
                class ClassB : classA
                {
                    public ClassB()
                    {
                        Console.WriteLine("ClassB constructor");
                    }
                }

新关键字的实时需求是什么?

当我们可以直接创建ClassA对象并调用ClassA的printA方法时,如果有意隐藏,为什么需要使用new关键字?

new关键字需求是为了引起您注意父类中的方法将被隐藏而不被覆盖的事实。

当涉及到OOP时,隐藏并不是最佳实践之一,虚拟方法更常见。IMHO c#编译器的开发人员决定,如果类声明的成员的签名与继承链上任何其他成员的签名相同,并且没有override前缀-这可能是一个错误,因此编译器询问是否有意隐藏。

除非您希望隐藏基类成员,否则不需要新关键字,然后您确实需要关键字,因为这就是c#语言的设计方式。如果没有它,代码将无法编译。

通常,在基类中声明函数而不在派生类中重新定义,或者定义基类函数虚函数(可被重写)或抽象函数(必须被重写)。

所以:ClassB可以在没有任何printA函数的情况下编写,因为它已经在基类中声明,而不是abstract:

class ClassB : classA
{
    public ClassB()
    {
        Console.WriteLine("ClassB constructor");
    }
    public void printB()
    {
        Console.WriteLine("ClassB-PrintB Method");
    }
}

上面的代码可以编译,printA可以从ClassB调用,但会使用ClassA的实现。

进一步,考虑如下:

        classA clsA = new ClassB();
        clsA.printA();
        new ClassB().printA();
输出:

ClassA构造函数

ClassB构造函数

ClassA-PrintA方法

ClassA构造函数

ClassB构造函数

B类扩展a类。不要把方法

您是否看到,当您实例化ClassB但将其存储在ClassA变量中时,您将获得该函数的ClassA版本的输出,而new ClassB.printA()返回ClassB版本的输出?


这听起来像你想有ClassB. printa()输出不同于ClassA.PrintA(),但你希望能够从ClassB的实例调用ClassA.PrintA()。可以通过将class . printa()声明为virtual来实现:

public class classA
{
    public virtual void printA()
    {
        Console.WriteLine("ClassA-PrintA Method");
    }
}

和重写ClassB中的函数:

class ClassB : classA
{
    public void printB()
    {
        Console.WriteLine("ClassB-PrintB Method");
    }
    public override void printA()
    {
        Console.WriteLine("Classb-PrintA Method");
        // Let's also call the ClassA version, just to show you how it works
        base.printA();
    }
}

为了证明这一点,我们也使用base关键字调用了ClassA版本。

void Main()
{
    new ClassB().printA();
}
控制台输出

:

Classb-PrintA方法

ClassA-PrintA方法