Пытаюсь осознать ООП... help

Вот что смог накидал. Тут создается класс Weapon, затем от него наследуются 2 класса Bow and Sword. В методе Main после создания экземпляров классов я хотел вызвать их методы Attack, но в консоли вернуло нулевые значения: "The null just attacked and dealt 0 damage!". Так вот суть вопроса: Почему оно возвращает мне нулевые значения? Ну и в целом если есть замечания буду рад если отметите.

Console.WriteLine($"The {Name} just attacked and dealt {Damage} damage!");
  class Weapon
  {
      public bool IsRange { get; set; }
      public bool IsMagic { get; set; }
      public string Name { get; set; }
      public int Damage { get; set; }
      public string Material { get; set; }

      public Weapon(bool isrange, bool ismagic, string name, int damage, string material) 
      {
          isrange = IsRange;
          ismagic = IsMagic;
          name = Name;
          damage = Damage;
          material = Material;
      }
  }

  class Bow : Weapon
  {
      public double ArrowFlightRange { get; set; }
      public Bow(bool IsRange, bool IsMagic, string Name, int Damage, string Material, double arrowFlightRange) : base(IsRange, IsMagic, Name, Damage, Material)
      {
          ArrowFlightRange = arrowFlightRange;
      }
      public void Attack()
      {
          Console.WriteLine($"The {Name} just attacked and dealt {Damage} damage!");
      }
  }
  
  class Sword : Weapon
  {
      public int Length { get; set; }
      public Sword(bool IsRange, bool IsMagic, string Name, int Damage, string Material, int lenght) : base(IsRange, IsMagic, Name, Damage, Material)
      {
          Length = lenght;
      }
      public void Attack()
      {
          Console.WriteLine($"The {Name} just attacked and dealt {Damage} damage!");
      }
  }
  class Program
  {
      static void Main(string[] args)
      {
          Bow bow = new Bow(true, false, "Elfin Bow", 20, "Star Steel", 120.5);
          Sword sword = new Sword(false, false, "Iron Sword", 8, "Iron", 1);

          bow.Attack();
          sword.Attack();
      }
  }

Ответы (1 шт):

Автор решения: aepot

Первая ошибка, вы не в ту сторону присваиваете в к конструкторе Weapon. Вам надо из аргумента в свойство, а не наоборот. Вот исправленный конструктор.

public Weapon(bool isRange, bool isMagic, string name, int damage, string material)
{
    IsRange = isRange;
    IsMagic = isMagic;
    Name = name;
    Damage = damage;
    Material = material;
}

Запускаем

The Elfin Bow just attacked and dealt 20 damage!
The Iron Sword just attacked and dealt 8 damage!

Работает!

Теперь про ООП. Обратите внимание на метод Attack. Он же работает только с данными базового класса, а ещё он 2 раза повторяется. А если будет 50 наследников, 50 раз будете повторять один и тот же код? Наверное суть ООП не в этом, и стоит использовать наследование. То есть перенести метод в базовый класс.

Просто удаляем из наследников метод Attack и вставляем в базовый класс Weapon, запускаем:

The Elfin Bow just attacked and dealt 20 damage!
The Iron Sword just attacked and dealt 8 damage!

Работает!

Теперь аргументы конструкторов. Зачем вы при создании лука передаете ему true в isRange? Наверное луков без дальней атаки не бывает, поэтому класс Bow должен заранее знать, что он дальнобойный. То же самое про признак магического оружия и т.д.

Вот исправленный полностью код.

class Weapon
{
    public bool IsRange { get; set; }
    public bool IsMagic { get; set; }
    public string Name { get; set; }
    public int Damage { get; set; }
    public string Material { get; set; }

    public Weapon(bool isRange, bool isMagic, string name, int damage, string material)
    {
        IsRange = isRange;
        IsMagic = isMagic;
        Name = name;
        Damage = damage;
        Material = material;
    }

    public void Attack()
    {
        Console.WriteLine($"The {Name} just attacked and dealt {Damage} damage!");
    }
}

class Bow : Weapon
{
    public double ArrowFlightRange { get; set; }

    public Bow(string name, int damage, string material, double arrowFlightRange) : base(true, false, name, damage, material)
    {
        ArrowFlightRange = arrowFlightRange;
    }
}

class Sword : Weapon
{
    public int Length { get; set; }

    public Sword(string name, int damage, string material, int length) : base(false, false, name, damage, material)
    {
        Length = length;
    }
}

class Program
{
    static void Main(string[] args)
    {
        Bow bow = new Bow("Elfin Bow", 20, "Star Steel", 120.5);
        Sword sword = new Sword("Iron Sword", 8, "Iron", 1);

        bow.Attack();
        sword.Attack();
    }
}

Ещё напутали немного в именовании с больших-маленьких букв. Аргументы в методе пишутся с маленькой буквы, а у вас в разнобой, это я тоже поправил. Будьте внимательней.

→ Ссылка