C#中“覆盖”和“隐藏”的区别

来源:互联网 发布:淘宝店铺可以买吗? 编辑:程序博客网 时间:2024/04/30 05:06
    在C#中,如果一个类的某个方法加了vitual的描述符,那么表示你可以在这个类的子类中重新实现该方法。Java中没有这么多废话,一个public或者protected方法不需要添加其它的描述符就可以在子类中被覆盖。
    class Program {
        
static void Main(string[] args) {
            Children c 
= new Children();
            Console.WriteLine(c.GetNumber());
            Console.WriteLine(((Father)c).GetNumber());
        }
    }

    
class Father {
        
public virtual int GetNumber() {
            
return 1;
        }
    }

    
class Children : Father {
        
public override int GetNumber() {
            
return 2;
        }
    }

结果:
2
2
    如果我们去掉Father类中GetNumber()方法的vitual描述符,那么在编译程序的时候会报错:
错误    1    “ConsoleApplication5.Children.GetNumber()”: 继承成员“ConsoleApplication5.Father.GetNumber()”未被标记为 virtualabstract 或 override,无法进行重写    D:我的文档Visual Studio 2005ProjectsWindowsApplication1ConsoleApplication5Program.cs    23    29    ConsoleApplication5
    这说明,如果在C#程序中,如果不在父类的方法中添加virtual、abstract或者override描述符,那么编译器就会认为你不想在子类中覆盖这个方法。如果我们同时去掉Children类中GetNumber()方法的override描述符,程序可以编译通过,但是这时就不是覆盖了,而是C#中的“隐藏”关系。“隐藏”和“覆盖”具体区别就是,如果是“隐藏”,那么在通过Father类型的引用调用一个Children对象的GetNumber()方法的时候,实际执行的部分是父类中的GetNumber()方法,而不是子类的。
    因此,可以简单的这么理解,“覆盖”就是重新实现了父类的方法,而“隐藏”只是把父类中的方法藏了起来,通过父类的引用来调用这个方法的时候,这个被“隐藏”的方法就被激活了。
class Program {
        
static void Main(string[] args) {
            Children c 
= new Children();
            Console.WriteLine(c.GetNumber());
            Console.WriteLine(((Father)c).GetNumber());
        }

    }


    
class Father {
        
public int GetNumber() {
            
return 1;
        }

    }


    
class Children : Father {
        
public int GetNumber() {
            
return 2;
        }

    }

结果:
2
1