【问题标题】:Is it possible to override a Method in a Base Class within the same Class (NOT a Derived Class)?是否可以在同一个类(不是派生类)中覆盖基类中的方法?
【发布时间】:2011-09-11 11:45:06
【问题描述】:

我的理解是,可以使用关键字override 从派生类重写基类中的方法(标记为Virtual)。

但是重写同一个类中的方法呢?

在我的具体情况下,我有一个类 x 有 2 个方法。方法ab 有一些共同的行为,b 为方法a 添加了功能。

过去,我在b 中复制了a 的代码,并将新功能添加到b 中。

我想知道是否有更好的方法,以便我可以集中方法 a 的行为。

    public class x
    {
       public static void a() {}
       public static void b() {}         
    }

【问题讨论】:

    标签: c# .net asp.net oop


    【解决方案1】:

    如果我理解正确,您的问题是方法 b 具有与方法 a 相同的代码加上更多代码。类似的东西

    public class x
    {
        public void a()
        {
            // a code
        }
    
        public void b()
        {
            // a code
    
            // b code
        }
    }
    

    如果是这种情况,您可以像这样在方法 b 中调用方法 a

    class x
    {
        public void a()
        {
            // a code
        }
    
        public void b()
        {
            a();
    
            // b code
        }
    }
    

    另一种情况是两种方法都有共同的代码:

    class x
    {
        public void a()
        {
            // common code
    
            // a exclusive code
        }
    
        public void b()
        {
            // common code
    
            // b exclusive code
        }
    }
    

    然后您可以将该代码提取到另一个方法中,如下所示:

    class x
    {
        public void a()
        {
            CommonMethod();
    
            // a exclusive code
        }
    
        public void b()
        {
            CommonMethod();
    
            // b exclusive code
        }
    
        private void CommonMethod()
        {
            // common code
        }
    }
    

    关于覆盖同一类中的方法。它被称为method overloading,但它允许您创建多个具有相同名称的方法,这些方法在输入类型方面彼此不同。

    这样

    class x
    {
        public string a(int i)
        {
        }
    
        public string a(string s)
        {
        }
    }
    

    唯一的限制是方法必须具有相同的返回类型(本例中为字符串)。

    【讨论】:

      【解决方案2】:

      您可以简单地从您的方法b() 中调用您的方法a()。不需要(也没有办法)覆盖方法。

      public class x
      {
         private static int _i = 0;
      
         public static void a() {
             _i = 1;
         }
         public static void b() {
             a();
             // here is _i = 1;
         }         
      }
      

      另一方面,您的方法可以有参数重载

      public class x
      {
         private static int _i = 0;
      
         public static void a() {
             a(1);
         }
         public static void a(int i) {
            _i = t;
            // common code which can use _i
         }         
      }
      

      在这种情况下,您可以调用a(1)a() 得到相同的结果。

      【讨论】:

        【解决方案3】:

        据我了解,可以使用关键字 override 从派生类中重写基类中的方法(标记为 Virtual)。但是同样覆盖同一个类中的方法呢?

        你不能这样做。虚拟方法用于Polymorphism,这是一种花哨的说法:

        如果您编写一个采用基类的方法,并将派生类传递给它,并且该方法调用基类上的方法,它会实际上调用派生实现。

        class A
        {
            public virtual void DoSomething() { Console.WriteLine("From A"); }
        }
        
        class B : A
        {
            public override void DoSomething() { Console.WriteLine("From B"); }
        }
        
        class C
        {
            public void DoSomethingMagic(A someClassInstance)
            {
                someClassInstance.DoSomething();
            }
        }
        
        class Program
        {
            public static void Main(string[] args)
            {
                A a = new A();
                B b = new B();
                C c = new C();
                c.DoSomethingMagic(a); // Prints "From A"
                c.DoSomethingMagic(b); // Prints "From B", even though it takes an A
        
                A bIsAnA = new B();
                c.DoSomethingMagic(bIsAnA); // Prints "From B", because B is also an A
            }
        }
        

        使用该定义,尝试“覆盖”同一类中的方法是没有意义的。

        在我的具体情况下,我有一个带有 2 个方法的类 x,方法 a 作为 b 的一些常见行为,b 向方法 a 添加功能。

        只需从b() 拨打a()

        public class x
        {
           public static void a()
           {
               // "base" implementation here
           }
        
           public static void b()
           {
               a();
               // extra implementation here
           }
        }
        

        【讨论】:

        • 感谢 Merlyn 的评论,我对您的信息投了赞成票。对我的理解很有帮助,谢谢
        • @GibboK:您可能还想看看这本书:计算机程序的结构和解释。它的主要目的是教你如何分解代码。它使用 Lisp,但它教授的每个概念都直接适用于任何现代语言。这本书也在网络上免费分发。 mitpress.mit.edu/sicp/full-text/book/book.html。网络上还有一个免费提供的视频系列,内容(或多或少)相同。
        【解决方案4】:

        您为什么不直接从b() 拨打a()

        public static void b()
        {
            // Do some stuff
            a(); // Do the common stuff
            // Do more stuff
        }
        

        【讨论】:

          【解决方案5】:

          您将公共部分拆分为第三个共享但私有的方法。

          【讨论】:

            【解决方案6】:

            你不能在同一个类中覆盖,你只能在派生类中这样做。您可以将方法的常见行为放在方法 a 中,然后从方法 b 中调用它。

            public static void a() 
            {
            // some common functionality
            }
            
            public static void b()
            {
            // do something
            a(); //call a
            //do something else
            }
            

            您可以根据需要多次从 b 中调用 a。

            【讨论】:

              猜你喜欢
              • 2011-06-01
              • 2017-06-22
              • 2018-12-17
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多