Overloading operators (like +,-,*,/) in abstract classes in C#

158 Views Asked by At

I am trying to implement the class Vector as an abstract one and have stuff like Vector2D and vector3D inherit from it. However, I ran into a problem with the overriding of operators, because they demand a static object reference be returned and I can't create one since I'm not allowed to call the abstract class' constructor there.

Here's the override I came up with:

    public static Vector operator +(Vector v1, Vector v2)
    {
        if (v1.Dimension != v2.Dimension)
        {
            throw new Exception("Vector Dimensions Must Be Equal");
        }
        else
        {
            double[] newMatrix = new double[v1.Dimension]; //the matrix for the new (resulting) vector 
            for (int i = 0; i < v1.Dimension; i++)
            {
                newMatrix[i] = v1.Matrix[i] + v2.Matrix[i];
            }
            return new Vector(newMatrix);
            //the abstract class has a constructor that takes a matrix
            //and constructs a vector based on it, but it can't be called here
        }
    }

I tried both using the matrix constructor and generating a new empty instance (I have either of those constructors). Both boil down to the "can't instantiate abstract class" error.

I am aware that I could implement the operations in each of the classes that will derive from Vector, but I hoped there is some workaround/technique/design pattern which solves the problem in a more elegant way, but I don't seem to find any article out there talking about overriding operators in abstract classes (maybe that approach makes no sense..?). Anyway, any help is highly appreciated. Here is the whole class, if needed:

using System;
using System.Text;

namespace PhysicsProblems
{
    public abstract class Vector
    {
        private static int IdCounter;

        protected readonly int ID;

        protected double[] Matrix;

        protected int Dimension
        {
            get
            {
                return Matrix.Length;
            }
        }

        public double Magnitude
        {
            get
            {
                double sum = 0;
                foreach (var value in Matrix)
                {
                    sum += value * value;
                }
                return Math.Sqrt(sum);
            }
        }

        public Vector(int dimension)
        {
            ID = IdCounter++;
            for (int i = 0; i < dimesion; i++)
            {
                Matrix[i] = 0;
            }
        }

        public Vector(double[] matrix)
        {
            ID = IdCounter++;
            matrix.CopyTo(Matrix, 0);
        }

        public static Vector operator +(Vector v1)
        {
            return v1;//to fix
        }
        public static Vector operator -(Vector v1)
        {
            for (int i = 0; i < v1.Matrix.Length; i++)
            {
                v1.Matrix[i] = -v1.Matrix[i];
            }
            return v1;//to fix
        }
        public static Vector operator +(Vector v1, Vector v2)
        {
            if (v1.Dimension != v2.Dimension)
            {
                throw new Exception("Vector Dimensions Must Be Equal");
            }
            else
            {
                double[] newMatrix = new double[v1.Dimension]; //the matrix for the new (resulting) vector 
                for (int i = 0; i < v1.Dimension; i++)
                {
                    newMatrix[i] = v1.Matrix[i] + v2.Matrix[i];
                }
                return new Vector(newMatrix);
                //the abstract class has a constructor that takes a matrix
                //and constructs a vector based on it, but it can't be called here
            }
        }

        public bool Equals(Vector vector)
        {
            if (vector.Dimension != Dimension) return false;

            bool check = true;
            for (int i = 0; i < Matrix.Length; i++)
            {
                if (vector.Matrix[i] != Matrix[i]) check = false;
            }
            return check;
        }

        public override bool Equals(object obj)
        {
            return Equals(obj as Vector);
        }

        public override int GetHashCode()
        {
            unchecked
            {
                int hash = 19;
                hash = (hash * 486187739) + ID.GetHashCode();
                hash = (hash * 486187739) + Dimension.GetHashCode();
                return hash;
            }
        }

        public override string ToString()
        {
            if (Dimension < 4)
            {
                var stringBuilder = new StringBuilder();
                for (int i = 0; i < Dimension; i++)
                {
                    stringBuilder
                        .Append(Constants.AxisLetters[i])
                        .Append(": ")
                        .Append(Matrix[i]);
                    if (i != Dimension - 1) stringBuilder.Append(", ");
                }
                return stringBuilder.ToString();
            }
            else
            {
                throw new NotImplementedException();
            }
        }
    }
}

And the inheriting class Vector2D:

using System;
using System.Text;

namespace PhysicsProblems
{
    public class Vector2D : Vector
    {

        public double X
        {
            get { return Matrix[0]; }
            set { Matrix[0] = value; }
        }

        public double Y
        {
            get { return Matrix[1]; }
            set { Matrix[1] = value; }
        }

        public Vector2D(int dimension) : base(dimension)
        { }
        public Vector2D(double[] matrix) : base(matrix)
        { }
    }
}

A little disclaimer I consider important: I'm fairly OK with OOP and have some experience, however, I took up C# a week or two ago. Therefore, rookie mistakes are to be expected

0

There are 0 best solutions below