【转】C#中隐藏(new)和方法重写(override)和重载(overload)

本文详细介绍了在面向对象编程中方法的重载与重写的概念及其应用。包括如何通过参数的不同实现方法的重载,以及如何通过继承实现方法的重写。同时对比了方法重写与隐藏的区别。

重载:同一个作用域内发生(比如一个类里面),定义一系列同名方法,但是方法的参数列表不同。这样才能通过传递不同的参数来决定到底调用哪一个。而返回值类型不同是不能构成重载的。

重写:继承时发生,在子类中重新定义父类中的方法,子类中的方法和父类的方法是一样的
        例如:基类方法声明为virtual(虚方法),派生类中使用override申明此方法的重写.

隐藏:基类方法不做申明(默认为非虚方法),在派生类中使用new声明此方法的隐藏。

重载时,根据参数选择调用的方法;
重写时,访问父类子类皆调用子类的重写方法;
隐藏时,访问父类则调用父类的方法,子类子类的方法。

隐藏(new)示例:

using    System;  
   class    A  
   {  
         public    void    F()    
         {  
               Console.WriteLine("A.F");    
         }  
   }  
   class    B:    A  
   {  
         new    public    void    F()    
         {    
               Console.WriteLine("B.F");    
         }  
   }  
   class    Test  
   {  
         static void Main(string[] args)
         {  
               B    b    =    new    B();  
               b.F();  
               A    a    =    b;    
               a.F();  
         }  
   }  
   输出为  
   B.F  
   A.F  

重写virtual(虚方法)示例  
   using    System;  
   class    A  
   {  
         public    virtual    void    F()    
         {  
               Console.WriteLine("A.F");    
         }  
   }  
   class    B:    A  
   {  
         public    override    void    F()    
         {    
               Console.WriteLine("B.F");    
         }  
   }  
   class    Test  
   {  
         static    void    Main()    
         {  
               B    b    =    new    B();  
               b.F();  
               A    a    =    b;    
               a.F();  
         }  
   }  
   输出为  
   B.F  
   B.F

补充:重写override一般用于接口实现和继承类的方法改写,要注意

   1、覆盖的方法的标志必须要和被覆盖的方法的标志完全匹配,才能达到覆盖的效果;
   2、覆盖的方法的返回值必须和被覆盖的方法的返回一致;
   3、覆盖的方法所抛出的异常必须和被覆盖方法的所抛出的异常一致,或者是其子类;
   4、被覆盖的方法不能为private,否则在其子类中只是新定义了一个方法,并没有对其进行覆盖。

### 什么是方法重写Override)? 方法重写是指在派生类中重新定义基类中声明为 `virtual`、`abstract` 或 `override` 的方法。通过重写,可以在子类中提供与父类不同的实现逻辑,同时保持方法签名一致[^4]。这样做的主要目的是实现多态性,即运行时根据对象的实际类型来决定调用哪个方法。 #### 示例:方法重写 ```csharp class Base { public virtual void Print() { Console.WriteLine("Print in Base"); } } class Derived : Base { public override void Print() { Console.WriteLine("Print in Derived"); } } ``` 在这个例子中,`Base` 类中的 `Print` 方法被标记为 `virtual`,表示它可以被子类重写;而 `Derived` 类使用 `override` 关键字提供了自己的实现[^3]。 --- ### 什么是方法重载Overload)? 方法重载是指在同一类中定义多个同名的方法,但这些方法的参数列表(参数的数量、类型或顺序)必须不同。返回值类型不能作为区分重载方法的依据。重载通常用于增强代码的可读性灵活性,使开发者可以根据不同的输入调用相同名称的方法。 #### 示例:方法重载 ```csharp class MathOperations { public int Add(int a, int b) { return a + b; } public double Add(double a, double b) { return a + b; } public string Add(string a, string b) { return a + b; } } ``` 上述代码中,`Add` 方法被多次定义,分别处理整数、浮点数字符串类型的加法操作。编译器会根据传入参数的类型自动选择合适的方法[^5]。 --- ### 方法重写重载的主要区别 | 特性 | 方法重写Override) | 方法重载Overload) | |------|----------------------|----------------------| | 所属类 | 发生在父子类之间 | 发生在同一个类内 | | 方法签名 | 必须完全相同 | 参数必须不同(数量、类型或顺序) | | 关键字 | 使用 `virtual` `override` | 不需要特殊关键字 | | 多态支持 | 支持运行时多态 | 不涉及多态机制 | | 访问权限 | 重写方法访问级别必须一致 | 可以有不同的访问修饰符 | --- ### 使用场景对比 - **方法重写**适用于希望子类改变从父类继承的方法行为的情况。例如,在图形绘制系统中,`Shape` 类可能有 `Draw()` 方法,而 `Circle` `Rectangle` 子类可以分别重写方法以实现各自形状的绘制逻辑。 - **方法重载**适用于希望一个方法名能适应多种数据类型的场景。例如,数学计算类中的 `CalculateArea()` 方法可以根据传入的参数(如半径、长宽等)计算不同几何图形的面积。 --- ### 注意事项 - 在进行方法重写时,必须确保基类方法是 `virtual`、`abstract` 或 `override` 的,否则无法覆盖其行为。 - 使用 `new` 关键字可以在子类中隐藏基类方法,但这不是真正的重写,也不会实现多态效果。 - 重载方法之间仅靠返回类型的不同是不合法的,因为 C# 编译器无法据此判断应调用哪一个方法[^5]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值