我有2个以上的对象来自不同的继承树,但我希望它们共享一组公共代码IMoveable
。
IMoveable
界面看起来不错,我对它的使用感到满意:
public interface IMoveable
{
/// <summary>
/// The speed the object travells between start and end
/// </summary>
int Speed { get; set; }
/// <summary>
/// The current velocity of the object
/// </summary>
Vector2 Velocity { get; set; }
/// <summary>
/// How far the object has travelled
/// </summary>
int DistanceTravelled { get; set; }
/// <summary>
/// The map the object is traversing
/// </summary>
Map Map { get; set; }
/// <summary>
/// Where the object was when they started moving
/// </summary>
Rectangle StartRectangle { get; set; }
/// <summary>
/// Where the object is right now
/// </summary>
Rectangle CurrentRectangle { get; }
/// <summary>
/// Where the object will be after moving
/// </summary>
Rectangle EndRectangle { get; set; }
/// <summary>
/// What will happen if the object walks to the "EndRectangle"
/// </summary>
Map.CollisionResults CollisionResult { get; set; }
/// <summary>
/// What happens if the object triggers a battle
/// </summary>
Action OnBattle { get; set; }
/// <summary>
/// How the object determines their movement
/// </summary>
Action SetMovement { get; set; }
}
使用该接口,我有一个方法:
private static void Move(IMoveable moveableOjb)
{
moveableOjb.Speed = 4;
if (moveableOjb.DistanceTravelled > 0)
{
moveableOjb.DistanceTravelled += moveableOjb.Speed;
if (moveableOjb.DistanceTravelled > Map.TileWidth)
{
moveableOjb.DistanceTravelled = 0;
moveableOjb.Velocity = new Vector2();
}
else
{
return;
}
}
moveableOjb.SetMovement();
if (moveableOjb.Velocity != Vector2.Zero)
{
moveableOjb.StartRectangle = moveableOjb.CurrentRectangle;
moveableOjb.EndRectangle = new Rectangle(
moveableOjb.CurrentRectangle.X + ((int)moveableOjb.Velocity.X * 10),
moveableOjb.CurrentRectangle.Y + ((int)moveableOjb.Velocity.Y * 10),
moveableOjb.CurrentRectangle.Width,
moveableOjb.CurrentRectangle.Height);
moveableOjb.CollisionResult = moveableOjb.Map.GetValue(moveableOjb.EndRectangle);
switch (moveableOjb.CollisionResult)
{
case Map.CollisionResults.None:
break;
case Map.CollisionResults.Colliding:
moveableOjb.Velocity = new Vector2();
break;
case Map.CollisionResults.Battle:
moveableOjb.OnBattle();
moveableOjb.Velocity = new Vector2();
break;
case Map.CollisionResults.OffRight:
case Map.CollisionResults.OffLeft:
case Map.CollisionResults.OffTop:
case Map.CollisionResults.OffBottom:
moveableOjb.Speed = 0;
break;
default:
break;
}
}
if (moveableOjb.Velocity != Vector2.Zero)
moveableOjb.DistanceTravelled += moveableOjb.Speed;
}
我面临的问题是这段代码很奇怪。我有一个静态的Move
方法,但我不知道将其放在哪里,而且我觉得我已经完全以错误的方式解决了这个问题。
对此,我必须采取的另一种方法是重写我的类,因此它们位于同一棵树中,而不是来自不同的继承。我可以这样做,但是要花一些时间进行重组。
我想我的主要问题是-我会以错误的方式进行操作,还是接近无法完全弄清的编码实践?
实施示例:
public class ClassA : Sprite, IMoveable
{
// interface implementation
public override Update(GameTime gameTime)
{
// Stuff
Move(this);
// More stuff
}
}
编辑:
我们已经得知,使用C#8可以使用默认的接口方法。我认为这可能正是我所需要的!
答案 0 :(得分:0)
您对static
的含义感到困惑。当方法影响特定实例时(如本例所示),它应该是非静态的。这就是“怪异”的来源。
静态方法适用于一般操作,或者虽然有利有弊,但也可以作为单例的替代方法。
将其定义为实现IMoveable
的类的成员或默认接口方法,而不是静态方法。没有实例作为参数。这样,实例this
将移动。您可以通过从该实例调用它来进行移动,这在语义上更有意义:
IMoveable moveableObj = //constructor here...
moveableObj.Move();
如果每个实现该接口的类都以相同的方式移动,您仍然可以避免将对实例的引用作为参数,而使用this
。必要时,也许这些参数最适合用于有关运动的信息。