隐藏和重写方法的区别

本文深入探讨了C#编程中方法隐藏与重写的概念,解释了两者的区别。隐藏方法发生在派生类中使用new关键字时,而重写方法涉及override关键字,与虚方法和接口实现有关。理解这两者对于优化面向对象的设计至关重要。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace csharp语法学习_多态
{
    class Program
    {
        static void Main(string[] args)
        {
            A[] arr = new A[]{ new A(), new B(), new C() };
            Console.WriteLine("print方法是被重写的, 则根据对象的实际类型来调用相应类的print方法");
            arr[0].print();
            arr[1].print();
            arr[2].print();
            Console.WriteLine("move方法是被隐藏的,则根据引用类型(A)来调用move方法, 即全部调用的是基类A中的方法");
            arr[0].move();
            arr[1].move();
            arr[2].move();
        }
    }
    class A
    {
        virtual public void print()
        {
            Console.WriteLine("class A print");
        }
        public void move()
        {
            Console.WriteLine("class A move");
        }
    }
    class B : A
    {
        override public void print()
        {
            Console.WriteLine("class B print");
     
### 方法隐藏重写与重载的区别 #### 方法隐藏(Method Hiding) 方法隐藏是指子类定义了一个与父类中完全相同的方法方法名、参数列表返回类型),但使用了 `new` 关键字(在 C# 中)或通过直接定义覆盖父类方法(在 Java 中)。隐藏方法的调用取决于变量的声明类型,而不是对象的实际类型。因此,方法隐藏是静态绑定的一种形式,也称为编译时绑定。例如: ```csharp class Parent { public void Show() { Console.WriteLine("Parent.Show"); } } class Child : Parent { public new void Show() { Console.WriteLine("Child.Show"); } } ``` 在上述代码中,如果使用 `Parent` 类型的变量引用 `Child` 对象并调用 `Show()` 方法,则会调用 `Parent` 的方法,而不是 `Child` 的方法。这表明隐藏方法的调用与变量的声明类型有关[^1]。 #### 方法重写(Method Overriding) 方法重写是指子类重新定义父类中已有的方法方法名、参数列表返回类型必须保持一致。重写方法的调用取决于对象的实际类型,而不是变量的声明类型。这是动态绑定的一种形式,也称为运行时绑定。例如: ```java class Animal { public void sound() { System.out.println("Animal makes a sound"); } } class Dog extends Animal { @Override public void sound() { System.out.println("Dog barks"); } } ``` 在上述代码中,即使使用 `Animal` 类型的变量引用 `Dog` 对象,调用 `sound()` 方法时仍然会执行 `Dog` 类的方法。这表明重写方法的调用与对象的实际类型有关[^2]。 #### 方法重载(Method Overloading) 方法重载是指在同一个类中定义多个方法,它们具有相同的名称但参数列表不同。重载方法的调用取决于传入的参数类型数量。这是静态绑定的一种形式,也称为编译时绑定。例如: ```java public class Calculator { public int add(int a, int b) { return a + b; } public double add(double a, double b) { return a + b; } } ``` 在上述代码中,`add()` 方法的调用将根据传入的参数类型选择合适的方法执行。这表明重载方法的调用与参数类型有关[^3]。 --- ### 方法隐藏重写与重载的对比 | 特性 | 方法隐藏 | 方法重写 | 方法重载 | |------|----------|----------|----------| | **定义** | 子类定义与父类相同的方法,使用 `new` 关键字(C#)或直接覆盖(Java) | 子类重新定义父类方法,使用 `@Override` 注解(Java)或 `override` 关键字(C#) | 同一个类中定义多个同名方法,参数列表不同 | | **绑定类型** | 静态绑定(编译时) | 动态绑定(运行时) | 静态绑定(编译时) | | **调用依据** | 变量的声明类型 | 对象的实际类型 | 传入的参数类型数量 | | **关键字** | `new`(C#) | `@Override`(Java) / `override`(C#) | 无特殊关键字 | | **作用范围** | 父类与子类之间 | 父类与子类之间 | 同一个类中 | --- ### 示例对比 #### 方法隐藏 ```csharp class Parent { public void Show() { Console.WriteLine("Parent.Show"); } } class Child : Parent { public new void Show() { Console.WriteLine("Child.Show"); } } // 调用示例 Parent p = new Child(); p.Show(); // 输出 "Parent.Show" ``` #### 方法重写 ```java class Animal { public void sound() { System.out.println("Animal makes a sound"); } } class Dog extends Animal { @Override public void sound() { System.out.println("Dog barks"); } } // 调用示例 Animal a = new Dog(); a.sound(); // 输出 "Dog barks" ``` #### 方法重载 ```java public class Calculator { public int add(int a, int b) { return a + b; } public double add(double a, double b) { return a + b; } } // 调用示例 Calculator calc = new Calculator(); calc.add(2, 3); // 调用 int add(int a, int b) calc.add(2.5, 3.5); // 调用 double add(double a, double b) ``` --- ### 总结 方法隐藏重写重载是面向对象编程中的三种不同机制。方法隐藏通过 `new` 关键字或直接覆盖父类方法实现,调用依据是变量的声明类型;方法重写通过 `@Override` 注解或 `override` 关键字实现,调用依据是对象的实际类型;方法重载通过参数列表的不同实现,调用依据是传入的参数类型数量。这三种机制分别体现了静态绑定动态绑定的不同特性,适用于不同的编程场景[^1]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值