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

abstrakcja w c#

Object Storage Arubacloud
+2 głosów
215 wizyt
pytanie zadane 12 marca 2023 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 2023 przez Wiciorny Ekspert (269,770 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 2023 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 2023 przez Wiciorny Ekspert (269,770 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,819 wizyt
pytanie zadane 27 sierpnia 2018 w Java przez periedynek Obywatel (1,320 p.)
0 głosów
1 odpowiedź 149 wizyt
pytanie zadane 8 maja 2018 w C i C++ przez michalnt Użytkownik (520 p.)
0 głosów
2 odpowiedzi 812 wizyt
pytanie zadane 27 lipca 2019 w C# przez TracerYT Początkujący (440 p.)

92,566 zapytań

141,420 odpowiedzi

319,609 komentarzy

61,952 pasjonatów

Motyw:

Akcja Pajacyk

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

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...