Reputation: 87
I have a Rectangle2d and a Rectangle3d deriving from it for backward compatibility reasons. In doing so, the type of the class' "transform" field shall change from Transform2d to Transform3d which is a derived version of Transform2d. Here's a simplified example:
class Transform2
{
protected float positionX;
protected float positionY;
}
class Transform3 : Transform2
{
protected float positionZ;
}
class Rectangle2d
{
protected Transform2 transform;
}
class Rectangle3d : Rectangle2d
{
// Does not work: Just hides Rectangle2d.transform
protected new Transform3 transform;
}
One solution I do not prefer is going without a Transform class and direct fields instead:
class Rectangle2d
{
protected float positionX;
protected float positionY;
}
class Rectangle3d : Rectangle2d
{
protected float positionZ;
}
In my eyes, when the second method works and the first method is just the second method with some bunching, there should be a clean solution for it. At least it hope so.
version: .NET Framework 4.6.1
Upvotes: 0
Views: 46
Reputation: 10593
What you're asking for is impossible, fields cannot be overriden. This is part of the reason why publicly visible (and protected
is publicly visible) fields are diacouraged by design guidelines. You can abstract it into a property, though:
class Rectangle2d
{
private Transform2d transform;
protected virtual Transform2d Transform => transform;
}
class Rectangle3d
{
private Transform3d transform;
protected override Transform2d Transform => transform;
}
Ideally your base class should rely as little as possible on the concrete transform
field and instead use the Transform
property. However, as a design suggestion, consider abstracting common behaviour into an abstract
RectangleBase
and have the 2D and 3D variants inherit from it, not from each other. You're on a path of creating a rather brittle base class out of Rectangle2d
as is now.
Upvotes: 1
Reputation: 136154
Inheritance implies an is-a
relationship. Rectangle3d
is not 2d, so it should probably not inherit from Rectangle2d
That said, If you must do this I suggest you use generics
public abstract class Transform<T>
{
protected T transform;
}
public class Rectangle2d : Transform<Transform2> {}
public class Rectangle3d : Transform<Transform3> {}
In this model both 2d and 3d have a property transform
which is strongly typed.
Upvotes: 1