Требуется уточняющая помощь — C # / ООП / Наследование / полиморфизм / Множественное наследование

#c# #oop #inheritance #polymorphism #multiple-inheritance

#c# #ооп #наследование #полиморфизм #множественное наследование

Вопрос:

Архитектура моей самоструктурированной проблемы

Класс героя (имя строки, int Health, int Gold)

Класс мага (строковое имя, int Health, int Gold, int Intelect) — каждый Маг — герой

Класс Archimage (имя строки, int Health, int Gold, int Intelect, int SpellsCast) — каждый Архимаг является магом

Класс воина (имя строки, int Health, int Gold, int Strength) — каждый воин — герой

Класс чемпиона (имя строки, int Health, int Gold, int Intelect, int DemonsSlain) — каждый чемпион — воин


Теперь часть, которая меня озадачивает: я хочу реализовать гибридные классы, которые наследуются от обеих ветвей дерева классов.

Класс паладина (строковое имя, int Health, int Gold, int Intelect, int Strength) — каждый паладин — маг и воин

Класс монаха (имя строки, int Health, int Gold, int Intelect, int Strength, int SpellsCast, int DemonsSlain) — каждый монах является Архимагом и чемпионом.

И давайте сделаем две диагональные:

Класс боевого мага (имя строки, int Health, int Gold, int Intelect, int Strength, int SpellsCast) — каждый боевой маг является Архимагом и воином.

Класс разрушителя заклинаний (имя строки, int Health, int Gold, int Intelect, int Strength, int DemonsSlain) — каждый разрушитель заклинаний является магом и чемпионом.


Код понятен после его запуска.

 
namespace Heroes_Of_Inheritance_And_Polymorphism
{
    class Program
    {
        static void Main(string[] args)
        {
            Hero Hero1 = new Hero("Arthur", 100, 50);
            Hero1.ShowStatus();

            Console.WriteLine("##########");

            Mage Hero2 = new Mage("Arthur", 100, 50, 120);
            Hero2.ShowStatus();

            Console.WriteLine("##########");

            Warrior Hero3 = new Warrior("Arthur", 100, 50, 120);
            Hero3.ShowStatus();

            Console.WriteLine("##########");

            Archimage Hero4 = new Archimage("Arthur", 100, 50, 120, 1000);
            Hero4.ShowStatus();

            Console.WriteLine("##########");

            Champion Hero5 = new Champion("Arthur", 100, 50, 120, 1000);
            Hero5.ShowStatus();
        }
    }

    public class Hero
    {
        public string Name;
        public int Health;
        public int Gold;

        public Hero(string name, int health, int gold)
        {
            this.Name = name;
            this.Health = health;
            this.Gold = gold;
        }

        public virtual void ShowStatus()
        {
            Console.WriteLine($"I am a Hero called {Name}, with {Health} health and {Gold} gold pieces!");
        }
    }

    public class Mage : Hero
    {
        int Intelect; 

        public Mage(string name, int health, int gold, int intelect) : base(name, health, gold)
        {
            this.Intelect = intelect;
        }

        public override void ShowStatus()
        {
            base.ShowStatus();
            Console.WriteLine($"I, {Name}, have now become a Mage with {Intelect} intelect.");
        }
    }

    public class Archimage : Mage
    {
        int SpellsCast;

        public Archimage(string name, int health, int gold, int intelect, int spellscast) : base(name, health, gold, intelect)
        {
            this.SpellsCast = spellscast;
        }

        public override void ShowStatus()
        {
            base.ShowStatus();
            Console.WriteLine($"I, {Name}, am a wise Archimage that has cast {SpellsCast} spells.");
        }
    }

    public class Warrior : Hero
    {
        int Strength;

        public Warrior(string name, int health, int gold, int strength) : base(name, health, gold)
        {
            this.Strength = strength;
        }

        public override void ShowStatus()
        {
            base.ShowStatus();
            Console.WriteLine($"I, {Name}, have now become a Warrior with {Strength} strength.");
        }
    }

    public class Champion : Warrior
    {
        int DemonsSlain;

        public Champion(string name, int health, int gold, int strength, int demonsslain) : base(name, health, gold, strength)
        {
            this.DemonsSlain = demonsslain;
        }

        public override void ShowStatus()
        {
            base.ShowStatus();
            Console.WriteLine($"I, {Name}, am a strong Champion that has slain {DemonsSlain} demons.");
        }
    }
}
 

Пока все хорошо, но это

 public class Paladin : Warrior, Mage
    {
        public Paladin(string name, int health, int gold, int Intelect, int Strength) 
            : base(name, health, gold, strength)
        {
        }
    }
 

очевидно, что это не сработает.

У меня возникает ощущение, что я должен использовать интерфейсы. Я не совсем уверен, как я могу извлечь необходимые параметры из нескольких классов в единственном интерфейсе, повторное использование их конструкторов в этом случае также поражает мой разум.

Любые указатели, жизнеспособные решения, критические замечания или совершенно разные подходы приветствуются!

С наилучшими пожеланиями! ^^

Комментарии:

1. хм, Но у ваших классов (Warrior и т. Д.) Не должно быть разных классов… это должен быть 1 класс, в котором хранятся значения… и у вас должны быть скорее экземпляры этого класса, назначенные для данного класса fx class ClassStats enum Classes , а затем Dictionary<ClassesEnum, ClassStats> … тогда Player класс будет иметь List<ClassesEnum> SelectedClasses свойство fx

2. Вы не можете выполнять множественное наследование в C #, и это хорошо! Вероятно, вам следует немного перепроектировать. Например, у вас есть коллекция Ability (или что угодно) объектов, которые вы можете предоставить каждому классу.

3. Стоит сначала прочитать это .

Ответ №1:

Поскольку @DavidG, упомянутый в комментарии выше, невозможен multiple inheritance C# , но есть некоторые вещи, которые вы можете сделать в зависимости от сценария:

  • Сначала просмотрите всю архитектуру, чтобы убедиться, что вам нужно множественное наследование, иногда с небольшими изменениями мы можем сэкономить много времени на исследования / внедрение.
  • Если после просмотра всего вам все еще нужно множественное наследование, есть несколько шаблонов, которые вы можете использовать, например interfaces , реализации или mixin pattern .

Вы можете подумать, mixin как добавить функциональные возможности к вашему объекту, допустим, вы можете инкапсулировать множество функциональных возможностей для ваших разных случаев run , таких как jump , attack , и т.д… (Смешивание).

Другим вариантом для достижения этой цели является имитация множественного наследования с помощью an interface , вы можете представить интерфейс как набор properties and functions , который реализует ваш объект, и implement это подразумевает, что вам нужно предоставить определение для тех функций внутри класса, которые implements это interface (интерфейсы).

Есть предложение разрешить реализацию метода внутри интерфейса для C#-8 , но это всего лишь предложение, надеюсь, что вышесказанное поможет прояснить проблему и укажет вам правильное направление 👍.