• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

abstrakcja w c#

Aruba Cloud PRO i VPS, Openstack, VMWare, MS Hyper-V
+2 głosów
62 wizyt
pytanie zadane 12 marca w C# przez piter11251 Obywatel (1,280 p.)

Witam! Uczę się języka C# tworząc projekt(jest taka próba imitacji niektórych elementów gry Margonem, apka konsolowa). Pewien zakres wiedzy mam z Javy, którą miałem na studiach ale trochę wychodzi niedokładne przyswojenie materiału i brak wiedzy z projektowania klas. Założyłem sobie, że klasa Character będzie abstrakcyjną klasą bazową dla każdej profesji(mag, paladyn, wojownik itd.) i dla każdej z tych profesji będą przypisywane jakieś podstawowe statystyki. Niestety zauważyłem, że miałbym dużo powielania kodu ze względu na robienie getterów i setterów. Np. u wojownika po zdobyciu nowego poziomu będzie przydzielane 5 pkt siły i 200 pkt życia, a dla maga 5 pkt inteligencji i 80 pkt życia. W jaki inny sposób mógłbym sobie rozdzielić strukturę tych klas aby uniknąć takiej duplikacji kodu? Poniżej kod
 

public abstract class Character
    {
        public string name { get; set; }
        private int healthPoints { get; set; }
        private int maxHealthPoints { get; set; }
        private int manaPoints { get; set; }
        private int maxManaPoints { get; set; }
        private int money { get; set; }
        private int strength { get; set; }
        private int agility { get; set; }
        private int inteligence { get; set; }
        private int energy { get; set; }
        private int attackStrenght { get; set; }
        private int armor { get; set; }
        private double attackSpeed { get; set; }
        private int lightningResistance { get; set; }
        private int fireResistance { get; set; }
        private int iceResistance { get; set; }
        private int poisonResistance { get; set; }
        private int dodge { get; set; }
        private int block { get; set; }
        private double criticalHit { get; set; }
        private double strenghtOfCriticalHit { get; set; }
        private int lvl { get; set; }

        public Character(string name)
        {
            this.name = name;
        }

        public abstract void Attack(Character target);
        public abstract void TakeTheDamage(int damage);
    }
class Warrior : Character
    {
        private string warriorName;
        private int healthPoints { get; set; }
        private int maxHealthPoints { get; set; }
        private int manaPoints { get; set; }
        private int maxManaPoints { get; set; }
        private int money { get; set; }
        private int strength { get; set; }
        private int agility { get; set; }
        private int inteligence { get; set; }
        private int energy { get; set; }
        private int attackStrenght { get; set; }
        private int armor { get; set; }
        private double attackSpeed { get; set; }
        private int lightningResistance { get; set; }
        private int fireResistance { get; set; }
        private int iceResistance { get; set; }
        private int poisonResistance { get; set; }
        private int dodge { get; set; }
        private int block { get; set; }
        private double criticalHit { get; set; }
        private double strenghtOfCriticalHit { get; set; }
        private int lvl { get; set; }
        public Warrior(string name) : base(name)
        {
            this.warriorName = name;
            this.healthPoints = 100;
            this.maxHealthPoints = 100;
            this.manaPoints = 0;
            this.maxManaPoints = 0;
            this.energy = 50;
            this.money = 0;
            this.dodge = 0;
            this.strength = 20;
            this.inteligence = 1;
            this.agility = 10;
            this.attackStrenght = 10;
            this.armor = 0;
            this.lvl = 1;
            this.attackSpeed = 1.0;
            this.block = 0;
            this.fireResistance = 0;
            this.iceResistance = 0;
            this.lightningResistance = 0;
            this.poisonResistance = 0;
            this.criticalHit = 5.0;
            this.strenghtOfCriticalHit = 1.0;
        }
        public string Name
        {
            get { return warriorName; }
            set { warriorName = value; }
        }

W klasie warrior mam jeszcze gettery i settery do reszty właściwości, ale nie chciałem ich tutaj wrzucać. W klasie Character konstruktor zrobiłem sobie testowo. Pozdrawiam

1 odpowiedź

+1 głos
odpowiedź 13 marca przez Wiciorny Ekspert (251,570 p.)

Możesz spróbować rozwiązać ten problem poprzez wykorzystanie dziedziczenia wielokrotnego. Możesz stworzyć klasę bazową, która zawiera podstawowe pola i metody dla każdej profesji, a następnie stworzyć klasy dziedziczące po klasie bazowej dla każdej profesji z dodatkowymi polami i metodami dla każdej z nich.

Na przykład, możesz stworzyć klasę bazową o nazwie "Character" z polami "Strength", "Intelligence", i "Health". Następnie możesz stworzyć klasy dziedziczące po klasie bazowej, takie jak "Warrior", "Mage", itd. dla każdej profesji.

W klasie dziedziczącej dla każdej profesji możesz zdefiniować dodatkowe pola i metody, które są specyficzne dla danej profesji, takie jak "Weapon" dla wojownika lub "Spell" dla maga.

W ten sposób unikniesz powielania kodu, ponieważ większość pól i metod będzie dziedziczona po klasie bazowej, a tylko specyficzne dla danej profesji elementy będą definiowane w klasie dziedziczącej.

np.
 

public class Character
{
    public int Strength { get; set; }
    public int Intelligence { get; set; }
    public int Health { get; set; }
}

public class Warrior : Character
{
    public string Weapon { get; set; }

    public void LevelUp()
    {
        Strength += 5;
        Health += 200;
    }
}

public class Mage : Character
{
    public string Spell { get; set; }

    public void LevelUp()
    {
        Intelligence += 5;
        Health += 80;
    }
}

 

komentarz 13 marca przez piter11251 Obywatel (1,280 p.)
Czyli tak naprawdę nie ma większej potrzeby robienia tutaj klasy abstrakcyjnej? Przynajmniej na tym etapie skomplikowania?
1
komentarz 13 marca przez Wiciorny Ekspert (251,570 p.)
Nie jestem autorem, to pytanie jest otwarte. Wcale nie oznacza, to że nie jest konieczna. Klasa abstrakcyjna może mieć również metody napisane do pól, wtedy każda klasa, która ją rozszerzy będzie miała getery/setery do pól wspólnych w klasie abstrakcyjnej.

Podobne pytania

0 głosów
4 odpowiedzi 1,554 wizyt
pytanie zadane 27 sierpnia 2018 w Java przez periedynek Obywatel (1,320 p.)
0 głosów
1 odpowiedź 116 wizyt
pytanie zadane 8 maja 2018 w C i C++ przez michalnt Użytkownik (520 p.)
0 głosów
2 odpowiedzi 702 wizyt
pytanie zadane 27 lipca 2019 w C# przez TracerYT Początkujący (440 p.)

90,871 zapytań

139,546 odpowiedzi

313,822 komentarzy

60,356 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Sklep oferujący ćwiczenia JavaScript, PHP, rozmowy rekrutacyjne dla programistów i inne materiały

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...