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

Nadpisanie dziedziczonego konstruktora i jednoczesne uniknięcie tworzenia obiektu bez spełnionego warunku.

VPS Starter Arubacloud
0 głosów
189 wizyt
pytanie zadane 29 marca 2020 w C# przez DlaFrajdy Nowicjusz (200 p.)

Witam,

Mam mały problem, dumam w jaki najlepszy sposób go rozwiązać..

Mam trzy klasy:

abstract public class BankAccount
    {
        protected string accountNumber;
        protected double amount;
        protected string currency;
        protected string pesel;

        public string AccountNumber { get { return accountNumber; } }
        public string Currency { get { return currency; } set { currency = value; } }
        public string Pesel { get { return pesel; } }

        public BankAccount(string pesel)
        {
            amount = 0;
            currency = "PLN";
            accountNumber = RandomAccountNumber();
            this.pesel = pesel;
        }
public class PersonalAccount: BankAccount
    {
        public PersonalAccount(string pesel):base(pesel)
        {
            amount += 5;
        }
    }

oraz 

class CurrencyAccount : PersonalAccount
    {
        public CurrencyAccount(string pesel, string currency) : base(pesel)
        {
            if (currency != "EUR" && currency != "USD" && currency != "GBP")
                Console.WriteLine("Nie można utworzyć konta walutowego w innej walucie niż \"EUR\", \"USD\" lub \"GBP\".");
            else
                this.currency = currency;


        }

    }

Dążę do tego, aby konto walutowe można było utworzyć jedynie w walutach EUR, USD, GBP.

Niestety w moim rozwiązaniu nawet po podaniu innej waluty i wyświetleniu komunikatu wykorzystywany jest domyślny [edit: nadrzędny, klasy BankAccount] konstruktor i tworzone jest nowe konto w walucie "PL".

Jak zgodnie ze sztuką rozwiązać ten problem? Chciałbym, aby możliwe było utworzenie konta walutowego w w/w walutach. 

class Program
    {
        static void Main(string[] args)
        {
            
            CurrencyAccount cu = new CurrencyAccount("89090982732", "sds");
            Console.WriteLine(cu.Currency);
            Console.WriteLine(cu.Pesel);
            Console.ReadKey();
            
            // wynikiem jest obiekt z cu.Currency = "PL"

        }
    }

Myślałem nad dorzuceniem enuma do klasy CurrencyAccount zawierającego możliwe waluty, jednak to nic nie zmieni - jeżeli warunek nie będzie spełniony dalej będzie tworzony obiekt z właściwością Currency ustawioną jako "PL".

Zdrowia w dzisiejszych czasach!

komentarz 29 marca 2020 przez JakSky Stary wyjadacz (14,770 p.)

Winna jest ta linijka:

currency = "PLN";

Zawsze będziesz tworzył obiekt BankAccount z wartością domyślną czyli currency = "PLN". 

komentarz 29 marca 2020 przez DlaFrajdy Nowicjusz (200 p.)

Dziękuję za odpowiedź! :)

Niestety nie pozwala na to treść ćwiczenia..

W konstruktorze klasy BankAccount ustawić pole amount na 0, walutę na PLN i wylosować numer konta. Oczekiwany format PL{22 wylosowane cyfry}.

Może autor miał na myśli, że nie można mieć konta walutowego bez posiadania konta w złotówkach ani nie można go otworzyć później..

 

komentarz 29 marca 2020 przez JakSky Stary wyjadacz (14,770 p.)
Rozwiązań jest dużo.

Możesz zrobić kilka konstruktorów o różnych parametrach.

Wtedy będzie można wywołać z klasy dziedziczadziedziczącej inny konstruktor(za pomocą base) i tym samym utworzyć konto z inną walutą.
komentarz 2 kwietnia 2020 przez Adii Użytkownik (960 p.)

Jak dla mnie to się trochę gryzie. Po 1. zamieniłbym currency na enum. 

public enum Currency {
 PLN,
 EUR,
 ...
}

Po 2, jeszcze przed tworzeniem obiektu możesz wykryć czy podana waluta jest przez Ciebie obsługiwana. Wystarczy napisać jedną metodę sprawdzającą:

public static bool IsCurrencyAvaiable(string currency)
{
 return Enum.IsDefined(typeof(Currency), currency);
}

Za pomocą tego main może teraz wyglądać:

class Program
{
   static void Main(string[] args)
   {
       CurrencyAccount cu = null;
       string accountNumber = "89090982732";
       string accountCurrency = "sds"

      if(IsCurrencyAvaiable(accoutCurrency))
      {
         cu = new CurrencyAccount(accountNumber, accountCurrrency);
         Console.WriteLine(cu.Currency);
         Console.WriteLine(cu.Pesel);
      }
      else
     {
        Console.WriteLine("Podana waluta nie jest wspierana");
     }

     Console.ReadKey();

   }
}

Polecam: Dobrym pomysłem wydaje się stworzenie klasy która będzie pilnowała czy według podanych parametrów można stworzyć odpowiednie konto bankowe. Klasa taka mogłaby się nazywać: "BankAccountManager" i to ona by pilnowała czy np. osoba z podanym peselem nie chce założyć ponownie konta i czy podana waluta jest obsługiwania. Warto się nad tym zastanowić.

Nie polecam: Można też w konstruktorze przy sprawdzaniu jaka to jest waluta rzucić wyjątek. To rozwiązanie z rzucaniem wyjątku nie wydaje mi się zbyt komfortowe. 

Nie polecam: Można też dodać flagę czy konto jest "prawidłowe", tutaj pytanie jednak po co tworzyć obiekt konta które prawidłowe nie jest?

komentarz 2 kwietnia 2020 przez DlaFrajdy Nowicjusz (200 p.)

Dziękuję za odpowiedź.

Połowicznie rozwiązałem problem w ten sposób:

(Wg. polecenia klasa obiekt klasy Bank musi posiadać metodę otwierającą konto walutowe, więc zrzuciłem na nią obowiązek sprawdzenia waluty).

 

public void openCurrencyAccount(Person person, string currency)
        {
            if (!availableCurrencies.Contains(currency))
                Console.WriteLine($"Bank nie otwiera kont w walucie {currency}");
            else if (isAccountExist(allCurrencyAccounts, person, currency))
                Console.WriteLine($"{person.FirstName} {person.LastName} PESEL: {person.Pesel} posiada już konto walutowe w {currency}. Nie można utworzyć drugiego konta!");
            else
            {
                CurrencyAccount cu = new CurrencyAccount(person.Pesel, currency);
                allCurrencyAccounts.Add(cu);
                Console.WriteLine($"Założono nowe Konto Walutowe dla numeru pesel {person.Pesel}. Konto ma numer: {cu.AccountNumber} a jego waluta to {currency}.");
            }
        }

Póki co możliwe waluty zapisałem w liście availableCurrencies<string>. Mimo, że skończyłem zadanie i wszystko działa to wczoraj przeglądałem jeszcze raz zadanie i też pomyślałem nad enumem, bo faktycznie pasuje on tutaj idealnie do tego korzystam w kilku metodach ze switcha, który się dobrze koleguje ze enumem.

Pozdrawiam!

Zaloguj lub zarejestruj się, aby odpowiedzieć na to pytanie.

Podobne pytania

0 głosów
1 odpowiedź 163 wizyt
0 głosów
0 odpowiedzi 131 wizyt

92,453 zapytań

141,262 odpowiedzi

319,088 komentarzy

61,854 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

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 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!

...