您可以声明实例级别的抽象方法,您的子类可以重写它:
public abstract class Vector
{
protected abstract Vector Add(Vector otherVector);
public static Vector operator +(Vector v1, Vector v2)
{
return v1.Add(v2);
}
}
public class SubVector : Vector
{
protected override Vector Add(Vector otherVector)
{
}
}
在处理多个子类(例如,
SubVector
是否需要知道如何与
SomeOtherSubVectorClass
相加?如果添加了
ThirdVectorType
类,会怎么样?)和处理 null 情况时可能会遇到一些问题。此外,要确保在进行可交换操作时,
SubVector.Add
的行为与
SomeOtherSubVectorClass.Add
相同。
编辑:根据您的其他评论,您可以进行以下操作:
public class Vector2D : Vector
{
public double X { get; set; }
public double Y { get; set; }
protected override Vector Add(Vector otherVector)
{
Vector2D otherVector2D = otherVector as Vector2D;
if (otherVector2D != null)
return new Vector2D() { X = this.X + otherVector2D.X, Y = this.Y + otherVector2D.Y };
Vector3D otherVector3D = otherVector as Vector3D;
if (otherVector3D != null)
return new Vector3D() { X = this.X + otherVector3D.X, Y = this.Y + otherVector3D.Y, Z = otherVector3D.Z };
}
}
public class Vector3D : Vector
{
public double X { get; set; }
public double Y { get; set; }
public double Z { get; set; }
protected override Vector Add(Vector otherVector)
{
Vector2D otherVector2D = otherVector as Vector2D;
if (otherVector2D != null)
return new Vector3D() { X = this.X + otherVector2D.X, Y = this.Y + otherVector2D.Y, Z = this.Z };
Vector3D otherVector3D = otherVector as Vector3D;
if (otherVector3D != null)
return new Vector3D() { X = this.X + otherVector3D.X, Y = this.Y + otherVector3D.Y, Z = this.Z + otherVector3D.Z };
}
}
编辑x2:
根据您最新的评论,也许您只需要维护一个内部数组/矩阵,并进行通用矩阵数学运算。您的子类可以针对数组索引公开X/Y/Z属性包装器:
public class Vector
{
protected double[] Values;
public int Length { get { return Values.Length; } }
public static Vector operator +(Vector v1, Vector v2)
{
if (v1.Length != v2.Length)
{
throw new VectorTypeException("Vector Dimensions Must Be Equal");
}
else
{
double[] newValues = new double[v1.Length];
for (int i = 0; i < v1.Length; i++)
{
newValues[i] = v1.Values[i] + v2.Values[i];
}
return new Vector() { Values = newValues };
}
}
}
public class Vector2D : Vector
{
public double X
{
get { return Values[0]; }
set { Values[0] = value; }
}
public double Y
{
get { return Values[1]; }
set { Values[1] = value; }
}
}
public class Vector3D : Vector
{
public double X
{
get { return Values[0]; }
set { Values[0] = value; }
}
public double Y
{
get { return Values[1]; }
set { Values[1] = value; }
}
public double Z
{
get { return Values[2]; }
set { Values[2] = value; }
}
}
EDITx3:根据您最新的评论,我猜想您可以在每个子类上实现运算符重载,在静态方法中处理共享逻辑(例如在基础向量类中),并在某个地方进行switch/case检查以提供特定的子类:
private static Vector Add(Vector v1, Vector v2)
{
if (v1.Length != v2.Length)
{
throw new VectorTypeException("Vector Dimensions Must Be Equal");
}
else
{
double[] newValues = new double[v1.Length];
for (int i = 0; i < v1.Length; i++)
{
newValues[i] = v1.Values[i] + v2.Values[i];
}
switch (newValues.Length)
{
case 1 :
return new Vector1D() { Values = newValues };
case 2 :
return new Vector2D() { Values = newValues };
case 3 :
return new Vector3D() { Values = newValues };
case 4 :
return new Vector4D() { Values = newValues };
default :
throw new DimensionOutOfRangeException("Do not support vectors greater than 10 dimensions");
}
}
}
那么你的子类将会有:
public class Vector2D
{
public static Vector2D operator +(Vector2D v1, Vector2D v2)
{
return (Vector2D)Add(v1, v2);
}
}
public class Vector3D
{
public static Vector3D operator +(Vector3D v1, Vector3D v2)
{
return (Vector3D)Add(v1, v2);
}
}
有一些重复,但我暂时想不出让编译器能够解决这个问题的方法:
Vector3 v1 = new Vector3(2, 2, 2);
Vector3 v2 = new Vector3(1, 1, 1);
var v3 = v1 + v2;
Console.WriteLine(v3.X + ", " + v3.Y + ", " + v3.Z);
或者对于其他维度:
Vector2 v1 = new Vector2(2, 2);
Vector2 v2 = new Vector2(1, 1);
var v3 = v1 + v2; //Vector2(3, 3, 3);
Console.WriteLine(v3.X + ", " + v3.Y); // no "Z" property to output!
VectorA
和VectorB
都派生自Vector
,那么VectorA + VectorB
的结果会是什么? - Austin SalonenVector
(这似乎主要是一个double
数组)的需求有些奇怪。您能否更详细地解释一下您的层次结构? - dlevprotected abstract Vector Add(Vector otherVector)
方法?这样你的运算符就可以在其中一个上调用虚拟方法,并允许子实现处理工作。 - Chris Sinclair