如何强制孩子调用父方法?

时间:2016-09-23 17:55:16

标签: c# parent-child

我有一个带有方法的基类。我想强制这个类的所有孩子在他们的代码中的某处调用这个基本方法。

public class BaseClass
{
    public void BaseMethod()
    {
        //Do something
    }
}

public class ChildClass1 : BaseClass
{
    public void ChildMethod()
    {
        BaseMethod();
    }
}

public class ChildClass2 : BaseClass
{
    public void ChildMethod()
    {
        //Doesn't call BaseMethod();
    }
}

所以我希望ChildClass1没问题,但我希望ChildClass2抛出错误。

我想这样做的原因是因为我的基类有一个我不想忘记在我的子类中实现的值。例如,如果我为一个游戏制造了一堆敌人,并且敌人类有一个速度修饰符,我不想忘记在所有的子方法中包含它:

public class Enemy
{
    public float x;
    public float y;

    private float speed;

    public float GetSpeed()
    {
        return speed;
    }

    public void SetSpeed(float speed)
    {
        this.speed = speed;
    }
}

public class Goomba : Enemy
{
    public void Move()
    {
        x += 5 * GetSpeed();
    }
}

public class Turtle: Enemy
{
    public void Jump()
    {
        y += 5;  //This is wrong.  I forgot to adjust for speed.
        //y += 5 * GetSpeed();  This is what I want to force myself to do
    }
}

虽然它实际上不适合移动。这是一个过于简单化的问题。基类包含能力修饰符,其中子类是使用修饰符的唯一能力。

如何构建代码,以便子代表在代码中的某处调用特定的父方法?

3 个答案:

答案 0 :(得分:1)

您可以使用TemplateMethod设计模式

public class BaseClass
{
    public void BaseMethod()
    {
          DoSomething();
          TemplateMethod();

    }
    protected abstract void TemplateMethod();     
}

因此,您使派生类实现模板方法,但该类的客户端调用BaseMethod方法。这会强制执行DoSomething()位,但允许派生类包含它们自己的逻辑。

在敌人的情况下这是一个简单的例子(obvs适应它以满足你的需要)。

public abstract class Enemy
{
    public float x;
    public float y;

    private float speed;

    public float GetSpeed()
    {
        return speed;
    }

    public void SetSpeed(float speed)
    {
        this.speed = speed;
    }

    public void Move()
    {
        x += GetMovementAmount() * GetSpeed();
    }

    public abstract decimal GetMovementAmount();
}

public class Goomba : Enemy
{
    public void GetMovementAmount()
    {
        return 5;
    }
}

public class Turtle: Enemy
{
    public void GetMovementAmount()
    {
        return 6;
    }
}

答案 1 :(得分:0)

创建新的课程能力。它将允许您控制运行时发生的情况,并且用户可以使运行执行任何他们想要的操作。

public class Ability
{
   Action myAct { get; set; }

   public Ability(Action inAct)
   {
      myAct = inAct;
   }

   public Run()
   {
     DoStuffBefore();
     myAct();
     DoStuffAfter();
   }   

}

答案 2 :(得分:0)

您可以重新排列代码,以便仅在基类中更改位置:

public class Enemy
{
    public float x { get; private set; }
    public float y { get; private set; }

    private float speed;

    public Move(float dx, float dy)
    {
        x += dx * speed;
        y += dy * speed;
    }
}