我正在编写一个计算二维空间和三维空间中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个问题:
答案 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)
首先,您不可能创建2DPoint
和3DPoint
类。接下来,我真的怀疑3D点应该从2D点继承。
至于你的问题,
答案 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()