Bạn có thể tuyên bố phương pháp trừu tượng dụ cấp mà lớp con của bạn có thể ghi đè lên:
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)
{
//do some SubVector addition
}
}
Có thể gặp phải một số vấn đề đặc biệt với nhiều lớp con (Will SubVector
đã biết làm thế nào để thêm với SomeOtherSubVectorClass
gì nếu bạn thêm ThirdVectorType
lớp?) Và có thể xử lý các trường hợp null. Ngoài ra, hãy đảm bảo rằng SubVector.Add
hoạt động giống như SomeOtherSubVectorClass.Add
khi nói đến các hoạt động giao hoán.
EDIT: dựa trên ý kiến khác của bạn, bạn có thể để một cái gì đó như:
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 };
//handle other cases
}
}
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 };
//handle other cases
}
}
EDITx2:
Với bình luận mới nhất của bạn, có lẽ bạn chỉ nên duy trì một mảng nội bộ/ma trận và chỉ làm chung ma trận toán học. lớp con của bạn có thể tiếp xúc với giấy gói X/Y/sở hữu Z so với indicies mảng:
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
{
//perform generic matrix addition/operation
double[] newValues = new double[v1.Length];
for (int i = 0; i < v1.Length; i++)
{
newValues[i] = v1.Values[i] + v2.Values[i];
}
//or use some factory/service to give you a Vector2D, Vector3D, or VectorND
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: Dựa trên nhận xét mới nhất của bạn, tôi đoán bạn có thể thực hiện quá tải toán tử trên mỗi lớp con, làm logic được chia sẻ trong một phương pháp tĩnh (nói trong lớp cơ sở Vector), và ở đâu đó làm một tấm séc chuyển/trường hợp để cung cấp một lớp con cụ thể:
private static Vector Add(Vector v1, Vector v2)
{
if (v1.Length != v2.Length)
{
throw new VectorTypeException("Vector Dimensions Must Be Equal");
}
else
{
//perform generic matrix addition/operation
double[] newValues = new double[v1.Length];
for (int i = 0; i < v1.Length; i++)
{
newValues[i] = v1.Values[i] + v2.Values[i];
}
//or use some factory/service to give you a Vector2D, Vector3D, or VectorND
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 };
//... and so on
default :
throw new DimensionOutOfRangeException("Do not support vectors greater than 10 dimensions");
//or you could just return the generic Vector which doesn't expose X,Y,Z values?
}
}
}
Sau đó, lớp con của bạn sẽ có:
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);
}
}
Một số sự trùng lặp, nhưng tôi không nhìn thấy một con đường xung quanh nó ra khỏi đỉnh đầu của tôi để cho phép trình biên dịch để làm điều này:
Vector3 v1 = new Vector3(2, 2, 2);
Vector3 v2 = new Vector3(1, 1, 1);
var v3 = v1 + v2; //Vector3(3, 3, 3);
Console.WriteLine(v3.X + ", " + v3.Y + ", " + v3.Z);
hoặc cho không gian khác:
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!
Lớp học có nguồn gốc của bạn trông như thế nào? – JotaBe
Có vẻ lạ với tôi rằng bạn sẽ cần phải phân lớp 'Vector' (xuất hiện chủ yếu là một mảng' double'.) Bạn có thể giải thích thêm một chút về thứ bậc của bạn không? – dlev
Kết quả của 'VectorA + VectorB' là gì, giả sử cả hai bắt nguồn từ' Vector'? –