Почему обьект вызывающий метод передает в качестве аргумента поле другого обьекта а не свое
class Unit
{
protected int _health;
protected int _damage;
public virtual void Attack(Unit unit)
{
unit.TakeDamage(_damage);//почему скелет вызывая метод передает аргументом поле _damage обьекта Archer?.. а не свое поле
}
public virtual void TakeDamage(int damage)
{
Console.WriteLine(damage);
if (damage >= _health)
{
_health = 0;
Die();
return;
}
_health -= damage;
}
protected virtual void Die() { }
}
class Skeleton : Unit
{
public Skeleton()
{
_health = 15;
_damage = 12;
}
public override void Attack(Unit unit)
{
Console.WriteLine("Скелет атакует.");
base.Attack(unit);
}
protected override void Die()
{
Console.WriteLine("Скелет убит.");
}
}
class Archer : Unit
{
public Archer()
{
_health = 50;
_damage = 15;
}
public override void Attack(Unit unit)
{
Console.WriteLine("Лучник атакует.");
base.Attack(unit);
}
protected override void Die()
{
Console.WriteLine("Лучник убит.");
}
}
class Program
{
static void Main(string[] args)
{
Archer archer = new Archer();
Skeleton skelet = new Skeleton();
archer.Attack(skelet);
archer.Attack(skelet);
}
}
Ответы (2 шт):
Это зависит не от объекта, а от параметров метода.
В вашем случае создан класс Unit, от которого наследуются Skeleton и Arhcer.
public override void Attack(Unit unit)
{
Console.WriteLine("Лучник атакует.");
base.Attack(unit);
}
В этой части кода в параметрах указан Unit. Это значит что сюда можно ставить класс Unit, либо его классы наследники.
И лучшник и скелет наследуются от Unit. И тот и другой имеют возможность вызвать методы Attack и TakeDamage.
В программировании (во всяком случае C#), если после наименования объета стоИт точка и имя метода, то метод вызвается у него и все свойства внутри этого метода, принадлежат этому объекту. Поэтому если написать car.Drive(), то свойства внутри метода будут от объекта car, а не ещё от какого-либо.
Если представить, что метод Attack не имеет паракметров, то при вызове archer.Attack(); свойство _damage всегда принадлежит к лучнику и никак иначе. Если skelet.Attack();, от свойство _damage всегда принадлежит к скелету и никак иначе. Аналогично с методом TakeDamage.
Еще раз: передаёшь ли ты агрументы в методы или нет, то _damage принадлежит только тому объекту, на котором вызыван метод.
Однако в методе Attack можно передать любой объект, унаследованный от Unit.
и тогда на строчке unit.TakeDamage вызовется метод TakeDamage какого объекта? Правильно, того, что передали как аргумент..То есть можно считать, что если передали skelet, то будет на самом деле не unit.TakeDamage, а skelet.TakeDamage. Если перередали как аргумент archer, то будет не unit.TakeDamage, archer.TakeDamage.
А что мы знаем о том, к чему применяется метод? Что свойства внутри метода будут от объекта, на котором вызвали метод. И получается, что если в качестве unit передали skelet, то это превращается в skelet.TakeDamage(XXX) и получается что у скелета начинает работать этот метод.