Reputation: 166
I started to learn C# but I am confused about something. Let's say I have a class and 2 subclasses. I have a method inside the parent class called Add(). But when I use this method with subclasses, since the method is asking for a "Toople" and not a "Vector" or a "Point", it gives me an error. How can I solve this issue? Is there a way to allow subclasses to be inserted into the method or should I create new methods for each different subclass? Thanks a lot.
using System;
namespace RayTracerChallange
{
public class Toople
{
public float x, y, z, w;
public Toople(float X, float Y, float Z, float W)
{
x = X;
y = Y;
z = Z;
w = W;
}
public Toople Add(Toople Toop)
{
return new Toople(this.x + Toop.x, this.y + Toop.y, this.z + Toop.z, this.w + Toop.w);
}
public class Point : Toople
{
Point(float X, float Y, float Z) : base(X, Y, Z, 1)
{
this.x = X;
this.y = Y;
this.z = Z;
}
}
public class Vector : Toople
{
Vector(float X, float Y, float Z) : base(X, Y, Z, 0)
{
this.x = X;
this.y = Y;
this.z = Z;
}
}
Upvotes: 0
Views: 813
Reputation: 3642
I don't understand the context fully, but probably I would just have a single class Toople
without the two others (Point
and Vector
) as they do not provide any additional functionality (or I would even use a struc
as this seems to be about ray tracing where speed is usually crucial).
Then I would add some operators to handle the addition, something like this:
public struct Toople {
Toople(float x, float y, float z, float w) {
X = x;
Y = y;
Z = z;
W = w;
}
public static Toople CreatePoint(float x, float y, float z) {
return new Toople(x, y, z, 1);
}
public static Toople CreateVector(float x, float y, float z) {
return new Toople(x, y, z, 0);
}
public Single X { get; }
public Single Y { get; }
public Single Z { get; }
public Single W { get; }
public static Toople operator +(Toople first, Toople second) {
checked {
return new Toople(first.X + second.X, first.Y + second.Y, first.Z + second.Z, first.W + second.W);
}
}
}
Upvotes: 0
Reputation: 6238
The closest you're going to get here is by making Toople
generic and abstract, possibly by doing something like this:
using System;
namespace RayTracerChallange
{
public abstract class ToopleBase<T> where T : ToopleBase<T>
{
public float x, y, z, w;
protected Toople(float X, float Y, float Z, float W)
{
x = X;
y = Y;
z = Z;
w = W;
}
protected abstract T MakeT(float X, float Y, float Z, float W);
public T Add(Toople Toop)
{
return makeT(this.x + Toop.x, this.y + Toop.y, this.z + Toop.z, this.w + Toop.w);
}
}
public class Toople : ToopleBase<Toople>
{
Toople(float X, float Y, float Z, float W) : base(X, Y, Z, W)
{
}
Toople MakeT(float X, float Y, float Z, float W)
{
return new Toople(X, Y, Z, W);
}
}
public class Point : ToopleBase<Point>
{
Point(float X, float Y, float Z) : base(X, Y, Z, 1)
{
}
protected override Point MakeT(float X, float Y, float Z, float W)
{
return new Point(X, Y, Z);
}
}
public class Vector : ToopleBase<Vector>
{
Vector(float X, float Y, float Z) : base(X, Y, Z, 0)
{
}
protected override Point MakeT(float X, float Y, float Z, float W)
{
return new Vector(X, Y, Z);
}
}
A couple things to note:
Toople
if you are following the Liskov Substitution Principle. (That is, the rest of the application should be able to expect any subclasses to behave in the same way as their base class, and should not even have the knowledge that the subclasses exist.)Upvotes: 1