为什么班级成员的价值没有变化?

时间:2017-08-09 20:10:46

标签: c#

我对编程很新,并且正在为练习制作RPG战斗模拟器。我的问题是我似乎无法使我的攻击方法有效。以下是我的课程:

class Person
{
    protected int attack;
    protected int health;

    public Person(int _attack, int _health)
    {
        attack = _attack;
        health = _health;
    }

    public int GetAttack()
    {
        return attack;
    }

    public int GetHealth()
    {
        return health;
    }

    public int Attack(int _health)
    {
        _health -= attack;
        return _health;
    }
}
class Hero : Person
{
    public Hero(int _attack, int _health)
        :base (_attack , _health)
    {

    }
}
class Enemy : Person
{
    public Enemy(int _attack, int _health)
        :base (_attack , _health)
    {

    }
}

并且主要是:

class Program
{
    static void Main(string[] args)
    {
        Hero Joe = new Hero(4, 10);
        Enemy Tim = new Enemy(5, 20);

        Joe.Attack(Tim.GetHealth());
        Console.WriteLine(Tim.GetHealth());
        Console.WriteLine(Tim.GetAttack());
        Console.ReadLine();
    }
}

我的猜测是攻击方法正在进行数学计算,但永远不会改变传递给它的健康状况。或者它可能与受保护的事实有关。我的另一个想法是,它不需要返回任何东西。 我将如何使我的攻击方法有效?我只是想让它拿出一些健康值,减去攻击事物的攻击值,并将计算出的值保存为健康状态?感谢您阅读本文!

4 个答案:

答案 0 :(得分:4)

当您传递int时,您正在复制该号码,而不是在内存中传递对相同号码的引用。

当你传递一个类的实例时,你 传递对内存中同一个对象的引用。

因此,我建议将您的设计更改为:

public void Attack(Person target)
{
    target.health -= this.attack;
}

...

Joe.Attack(Jim);

答案 1 :(得分:3)

你可以在这里改进几件事。首先是命名约定,我建议阅读design guidelines

首先,如果您将Attack and Health更改为属性而不是受保护字段,则会为其公开getter和setter方法。显然你只想设置控制器的形式,所以让set成为private set

public class Person
{
    public int Attack { get; private set; }
    public int Health { get; private set; }

    public Person(int attack, int health)
    {
        Attack = attack;
        Health = health;
    }

    // Rest of code
}

当您这样做时,您无需使用个人GetAttack()GetHealth()方法。

接下来,Attack()中参数的名称会产生误导。我假设您希望参数为" attack"而不是"健康"对?由于我们的setter是私有的,因此这种方法允许我们只访问里面的健康修改。由于我们已将Health更改为属性,因此我们不再需要将其返回,因此此方法现在可以void

//Our property is named Attack so this has to be AttackAction or something different
public void AttackAction(int attack)
{
    Health -= attack;
}

如果我们把它们放在一起:

public class Person
{
    public int Attack { get; private set; }
    public int Health { get; private set; }

    public Person(int attack, int health)
    {
        Attack = attack;
        Health = health;
    }

    public void AttackAction(int attack)
    {
        Health -= attack;
    }
}

public class Hero : Person
{
    public Hero(int attack, int health)
        :base (attack , health)
    {

    }
}

public class Enemy : Person
{
    public Enemy(int attack, int health)
        :base (attack , health)
    {

    }
}

我制作了一个小提琴here,显示了这个新代码。

答案 2 :(得分:0)

您正在调用Attack(),但永远不会保存该方法返回的值。您需要为health字段添加Setter,然后将该值设置为方法的返回值。像

这样的东西

健康财产

public int Health
{
    get { return health; }
    set { health = value; }
}

设置值

Tim.Health = Joe.Attack(Tim.Health);

答案 3 :(得分:0)

如果你想保持设计模式不变(你没有,请参阅Blorgbeard的回答)你可以向Person添加一个SetHealth()方法并执行以下操作:

Tim.SetHealth(Joe.Attack(Tim.GetHealth());

这会得到Tim的健康总数,将其传递给Joe的攻击方法,该方法返回一个值(Tim的新生命值应该是什么),然后将Tim的生命值设置为此值。