Yes but separate classes make the distinction between them clear, and it help avoids silly things like -
aMatrixAsAVector.dotProduct(aMatrix);
I would STRONGLY disagree. Defining seperate classes just to "make the distinction between them clear" is a very bad reason to do so.
The fundamental reason why you want them to be same class is because they are the same. You can share the operators among them. Remember that you can multiply vectors to matrices, matrices to vectors and matrices to matrices and vectors to vectors.
You will need to define 4 operators to accomplish these. But with common class, you can just define one overloaded operator for every operation. It makes the code look a lot cleaner and it will allow you to scale it very easily.
This approach is very common in Matlab and many other math suites. They don't differentiate between vectors and matrices. Vectors are just matrices with one row/column.
The error case you mentioned,
aVectorAsAMatrix DOT aMatrix
is no different from:
aVectorOfOneSize DOT aVectorOfaDifferentSize
Both the above operations fail because of their non matching sizes. So differentiating the classes wouldn't help since you would still have to error out with the sizes of two vectors are different.
The two operations would exception out in the same way:
if(LeftOperand.isVector && rightOperand.isVector && leftOperand.Size == rightOperand.Size)
---transpose the leftOperand into a row vector and multiply with the rightOperand as a column vector.
ELSE
---throw exception
.isVector does nothing but check if one of the dimensions is = 1 and .Size is a struct that holds x and y dimensions.
This works the right way for vectors and matrices.
Hence there is no reason to unnecessarily duplicate the classes.
This is just my preference but I do my assignments in C and Obj-C/C++ (Depending on the assignment if it needs OOP). C# is a nice language (I prefer it over Java), but all that syntax sugar is why I don't use it for Uni projects. I want to learn how the actual logic behind it works, spending the time to get it work in something like C will be more beneficial than getting it to work in a sugar coated language like C#.
Whatever language you choose, the basic concepts are all the same. The more complex concepts however, are not available in C. For OOP you would need to go C++ as is not available in C. C# offers even more with reflection etc.