关于.net:重载,覆盖和隐藏?

Overloading,Overriding and Hiding?

有人能解释什么是重载、重写和隐藏在.NET中吗?

谢谢


重载是对单个方法或运算符的多个可能"签名"的定义。每个签名采用不同的参数,本质上是一个不同的函数,与多个函数具有不同的名称没有区别。这通常用于在概念上对类似的操作进行分组,例如重载+以使用BigIntegerString:这两个操作似乎都使用+来表示(除非您认为+的所有重载都应定义abel组,否则String重载不会定义)。

重写是对同一方法签名的多个可能实现的定义,这样,实现由第零个参数的运行时类型(通常由C中的名称this标识)决定。

隐藏是派生类型中方法的定义,其签名与它的一个基类型中的签名相同,但不进行重写。

覆盖和隐藏的实际区别如下:

  • 如果方法被重写,则要调用的实现基于参数this的运行时类型。
  • 如果方法只是隐藏的,则要调用的实现是基于参数this的编译时类型。

重载提供了多个具有相同名称和不同签名的方法:

1
2
void Foo() {...}
void Foo(int i) {...}

重写在继承中用于更改每个子类的实现:

1
2
3
4
5
6
7
8
class SomeBase {
    public virtual void Foo() {}
}
class SomeOther : SomeBase {
    public override void Foo() {
        // different implementation, possibly calling base.Foo();
    }
}

有了上面的内容,即使我做到了:

1
2
SomeBase obj = new SomeOther();
obj.Foo();

它将调用SomeOther.Foo实现。调用的方法取决于实例类型,而不是变量。

方法隐藏则相反;它替换了方法签名,但仅当从派生类型调用方法时才适用:

1
2
3
4
5
6
7
8
class SomeBase {
    public void Foo() {}
}
class SomeOther : SomeBase {
    public new void Foo() {
        // different implementation, possibly calling base.Foo();
    }
}

现在:

1
2
3
4
SomeOther obj = new SomeOther();
SomeBase baseObj = obj;
obj.Foo(); // calls SomeOther.Foo
baseObj.Foo(); // calls SomeBase.Foo

也就是说,方法调用依赖于变量,而不是实例。


重载是指使用不同参数创建多个方法时。例如:

1
2
3
4
5
6
7
8
9
10
11
12
public class Car
{
  public Car()
  {
    // Do stuff
  }

  public Car(int numberOfCylinders)
  {
    // Do stuff
  }
}

您可以看到构造函数具有相同的名称,但参数不同。您将在Visual Studio中看到IntelliSense中的重载方法和构造函数,其中有向上和向下的小箭头,因此您可以浏览签名。

重写是指从基类为方法提供新的实现。例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
   public class Square
   {
      public double x;

      // Constructor:
      public Square(double x)
      {
         this.x = x;
      }

      public virtual double Area()
      {
         return x*x;
      }
   }

   class Cube: Square
   {
      // Constructor:
      public Cube(double x): base(x)
      {
      }

      // Calling the Area base method:
      public override double Area()
      {
         return (6*(base.Area()));
      }
   }

请注意,在C中,不能重写非虚拟或静态方法。


假设您理解其他海报给出的解释,记住重载和重写之间的区别的一种方法是,使用重载时,可能存在同名函数的"加载"。

傻,我知道,但它对我有用。


重载是多语素的一个例子,可以在两种方法之间传递多语数、数据类型和参数序列。

覆盖(与虚拟不同)意味着存在一些已定义的功能,但是您可以在继承时给出更清晰的概念。

隐藏意味着隐藏内部特征并表示基本特征,OOP概念的特征之一。

谷歌获取详细信息


简单来说:

重载是指具有相同的方法名和不同的签名。这可以在同一个类中。如:

1
2
3
4
5
6
7
8
int Add (int a, int b)
{
  return a + b; // returns int
}
float Add (float a, float b)
{
return a + b; // returns float
}

重写是指派生类中的方法名和签名与基类中的方法名和签名相同。在这个场景中,我们说派生类重写了基类方法。哪个方法运行取决于哪个实例调用该方法

例如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Shape
    {
        public virtual void Draw() { }

    }

    public class Square : Shape
    {
        public override void Draw()
        {
            // Code to draw square
        }
    }

    public class Circle : Shape
    {
        public override void Draw()
        {
            // Code to draw circle
        }
    }

隐藏或封装是当您声明一个类的成员变量和方法是私有的,这样其他类甚至派生类都无法访问它们。

例如。

1
2
3
4
5
6
private int onlyICanAccess;

private void OnlyICanExecute()
{
  // ...
}