C#覆盖可能性

时间:2011-03-23 12:42:38

标签: c# override

我正在编写一个计算二维空间和三维空间中2个点之间距离的程序。

我创建了两个类“2DPoint”和“3DPoint”。 3DPoint继承自2DPoint。

我在2DPoint中有一个“calculateDistance”方法,我想在3DPoint中覆盖。

以下是2DPoint中的代码:

 public virtual double calcDistance(int xco1, int xco2, int yco1, int yco2)
 {

        .....(some maths)


            return distance;
 }

现在问题就是在3DPoint中我必须输入X,Y然后Z坐标2点,所以通过在3DPoint类中声明“覆盖”它不会让我覆盖2D Point中的方法

e.g。

public override double calcDistance(int xco1, int xco2, int yco1, int yco2, int zco1, int zco2)
 {

        .....(some maths)


            return distance;
 }

所以我有3个问题:

  1. 是否可以使用覆盖命令覆盖2DPoint calcDistance 我如何编写代码?
  2. 如果没有解决我的问题使用覆盖命令?
  3. 超载与覆盖相同,因为这是我能看到的唯一方法。

6 个答案:

答案 0 :(得分:4)

这是一个相对简单的误解。

  • 覆盖是一种改变子类中例程行为的方法。重写方法与原始方法具有相同的参数。
  • 重载是指具有相同名称但参数不同的方法。编译器通过匹配参数找出你的意思。

我看不到足够的代码知道你的基本设计是否合理,但从表面上看,似乎你需要使用重载。

答案 1 :(得分:1)

您不必重写双参数函数,只需使用3个参数创建一个新函数。创建3d实例时,它将对调用源可见。通过具有3个参数的不同“签名”(或甚至相同的参数#,但是不同的类型),编译器将知道它应该调用哪个函数。例如:

public class Calc2d
{
   public virtual CalcDistance( int Parm1, int parm2 )
   { ... }
}

public class Calc3d : Calc2d
{
   public virtual CalcDistance( int Parm1, int parm2, int Parm3 )
   { ... }
}

在3d类中,CalcDistance的BOTH实例将是可见的,但是根据传递的参数数量将决定调用哪个实例。

答案 2 :(得分:1)

首先,您不可能创建2DPoint3DPoint类。接下来,我真的怀疑3D点应该从2D点继承。

至于你的问题,

  1. 覆盖要求参数相同(简单地说)
  2. 不,这里没有什么可以覆盖的
  3. 是的,重载与重写
  4. 不同

答案 3 :(得分:0)

1)您无法更改覆盖方法时所采用的参数。如果您尝试这样做,您最终将在子类上使用两种方法。

3)重载是一种方法,它采用不同的参数集,例如Calc(int x)Calc(int x, int y)。这与覆盖更改不同,因为覆盖更改了一个类中的行为与其基类的行为相比。

你可以做很多事情之一:

i)使您的方法在界面上运行。 IPOINT。检查IPoint的类型,如果它是2DPoint并且您期望3dPoint然后抛出异常。您可以添加泛型以使其强类型化。这可能就是我要采取的方法。它确保您调用正确的方法,并在编译时而不是运行时进行抱怨。

interface IPoint<TPoint> where TPoint : IPoint
{
   Double CalcuateDistance(TPoint point);
}

public class 2DPoint : IPoint<2DPoint>
{
   public Double X { get; set; }
   public Double Y { get; set; }
   public Double CalculateDistance(2DPoint point)
   {
      // some maths using this.X/this.Y and point.X/point.Y
   }
}

public class 3DPoint : IPoint<3DPoint>
{
   public Double X { get; set; }
   public Double Y { get; set; }
   public Double Z { get; set; }

   public Double CalculateDistance(3DPoint point)
   {
      // some maths using this.X/this.Y/this.Z and point.X/point.Y/point.Z
   }
}

使用这种方法,如果您对两种类型的点都有共同的功能,则可以将其放在基本抽象类中,而不是AbstractPoint<TPoint> : IPoint<TPoint>。如果你这样做,你会定义:

abstract class AbstractPoint<TPoint> : IPoint<TPoint>
{
   public virtual double CalculateDistance(TPoint point);
}

当您在2DPoint和3DPoint中覆盖它时,您将自动传入正确类型的TPoint:)

ii)使你的基类方法取z,其默认值为0.只需为所有2D点传入0。这与你的基础上有两个方法相同(一个采用z,一个不采用,并在正确的时间调用正确的方法)

Calc(int x, int y, int z = 0);

iii)删除继承并有2个单独的概念类。

答案 4 :(得分:0)

你不应该让3DPoint成为2DPoint的子类,因为这不是一个is-a关系。 2D点不是3D点的概括,只是不同而不应该从另一点继承。

是的,我不明白你的方法签名public virtual double calcDistance(int xco1, int xco2, int yco1, int yco2)。它采用点的坐标,即使它是一个实例方法,因此总是在特定点上执行。像public virtual double calcDistance(2DPoint other)这样的东西对我来说更有意义。

答案 5 :(得分:0)

更好地设计你的问题并适当地使用多态将是创建2D点类,它在构造函数中接受4参数(Xs和Ys)。然后是一个3D点类,它接收6个参数(Xs,Ys和Zs)。

然后你将写入2DPoint

public virtual double calcDistance() 

和3DPoint

public override double calcDistance()