Wątek przeniesiony 2015-11-09 13:43 z C# i .NET przez ŁF.

Dwa konstruktory i zależność między nimi - C# konsola

0

Witam,

Mam do zrobienia dwa konstruktory. Jeden ma ustawiać wartości np. pojemnosc, ilosc i ogólna wielkość. Jeśli użytkownik nie poda w pierwszym konstruktorze ogólnej wielkości to w drugim konstruktorze ogólna wielkość ma przyjąć wartość domyślną, czyli obojętna wartość którą przypisałem do jakiegoś pola, w tym przypadku "temp". I stąd moje pytanie jak to zrobić? I jak wyglądać będzie wywołanie pierwszego i drugiego konstruktora w programie głównym? To że pola są readonly to jest warunek konieczny.

 
        double temp = 50;
        readonly double Pojemnosc;
        double Ilosc;
        readonly double Wielkosc;

        public Klasa(double pojemnosc, double ilosc, double wielkosc1)
        {
            Pojemnosc = pojemnosc;
            Ilosc = ilosc;
            Wielkosc = wielkosc1;
            pojemnosc = Double.Parse(Console.ReadLine());
            ilosc = Double.Parse(Console.ReadLine());
            wielkosc1 = Double.Parse(Console.ReadLine());
            Console.WriteLine(pojemnosc + "," + ilosc + "," + wielkosc1);
           
        }

        public Klasa(double wielkosc1)
        {
            wielkosc1 = temp;
        }

To część mojego kodu, prosiłbym o wyrozumiałość bo zaawansowanym programistą nie jestem - jeszcze :)

0

Do konstruktora musisz podać już wcześniej wczytane dane, a nie próbować w nim wczytać dane. Po pobraniu danych od użytkownika wywołujesz konstruktor.

0

rozumiem że muszę to zrobić w tej samej klasie co jest konstruktor?

1

Jak chcesz w tej samej klasie pobrać dane skoro dopiero na podstawie danych pobranych od użytkownika chcesz stworzyć obiekt tej klasy? ;)
Skoro piszesz o aplikacji konsolowej, dane pobierasz w funkcji Main, po pobraniu danych od użytkownika dane, które są wymagane do Twojego konstruktora. Po wczytaniu danych tworzysz obiekt klasy wywołując konstruktor. W skórcie:

class Program
    {
        static void Main(string[] args)
        {
            //pobierasz dane od użytwkonika (pamiętaj o obsłudze błędów, jeżeli użytkownik poda znaki, a będziesz chciał mieć wartość liczbową
            var tmp = Console.ReadLine();
            //tworzysz obiekt swojej  klasy
             var yourObject = new MyClass(tmp);
           //wypisujesz do konsoli wartości obiektu
            Console.WriteLine(yourObject.Value.ToString());
            Console.ReadLine();

        }
    }

    class MyClass
    {
        public int Value {get;set;}

        public MyClass(int value)
        {
            this.Value = value;
        }
    }
0

Drugi konstruktor powinien wyglądać chyba tak:


        public Klasa(double pojemnosc, double ilosc)
        {
            Pojemnosc = pojemnosc;
            Ilosc = ilosc;
            Wielkosc = temp;
 
        }
 
 
0

Ok, rozumiem już jak to powinno być poukładane. Można czymś zastąpić typ var, nie spotkałem się z nim póki co i nie chciałbym go używać ;)

0

Var - to słowo kluczowe, które podczas kompilacji zostanie "zamienione" na odpowiedni typ. Jeżeli potrzebujesz liczby rzeczywistej możesz jawnie zadeklarować double. A w wolnej czasie doczytaj o Var.

0

Pytania w komentarzach...

 class Program : Klasa 
    {
        static void Main(string[] args)
        {
            
            Program t = new Program(); // <- to nie potrzebne?
            Klasa a = new Klasa();   // <- czy to nie potrzebne?
            a.Pojemnosc = Double.Parse(Console.ReadLine()); // <-  "a." czy "t." ? 
            a.Ilosc = Double.Parse(Console.ReadLine());
            // jak wywolac konstruktor aby po wpisaniu tych wartosci byly one przypisane ?


class Klasa
{

        public double Pojemnosc;
        public double Ilosc;
        public readonly double Wielkosc;
        public double temp = 50;

        public Klasa(double pojemnosc, double ilosc, double wielkosc1) // wielkosc1 <- potrzebna jeśli do Wielkosci przypisuje temp? raczej nie..
        {
            Pojemnosc = pojemnosc;
            Ilosc = ilosc;
            Wielkosc = temp;
            Console.WriteLine(pojemnosc + "," + ilosc + "," + temp);
        }

        public Klasa()
        { }
0

Jeśli użytkownik nie poda w pierwszym konstruktorze ogólnej wielkości to w drugim konstruktorze ogólna wielkość ma przyjąć wartość domyślną.

Nie możesz mieć po prostu jednego konstruktora z argumentem opcjonalnym?

public Klasa(double pojemnosc, double ilosc, double wielkosc1 = 50) { ... }
0

Nie tworzysz obiektu klasy Program,
Wartości pobrane od użytkownika przypisujesz do zmiennych(po to aby wykorzystać konstruktor, jeżeli masz publiczne pola w klasie możesz i tak przypisywać wartości ale o to nie teraz tym).
Klasa

"Klasa"

, powinna być poza klasą Program

, Klasa<code class="csharp"> Program

nie dziedziczy po Klasa

. Nie będę Ci pisał rozwiązania bo nie o to w tym chodzi. Przeczytaj jakiś kurs i na wszystkie swoje pytania uzyskasz odpowiedź.
0

To tylko część programu, mam w klasie "Klasa" inne metody, pola itd. i chciałem mieć do nich dostęp w programie głównym.

W zadaniu mam jasno napisane że: "Poza ustawieniem pojemnosci i ilosci drugi konstruktor umożliwi ustawienie Ogólnej wielkości" i aby to zrobić mam skorzystać z pierwszego konstruktora, czyli tak naprawdę mam mieć dwa konstrukory, jeden ustawia pojemnosc i ilosc a drugi ustawia na wartość domyślną (opcjonalną) ogólną wielkość. :)

I nie chce rozwiązania, chcę to zrozumieć :)

0

Aby mieć dostęp nie musisz dziedziczyć, i raczej wydaje mi się że nie konieczne jest łapanie się za dziedziczenie jeżeli jest problem ze stworzeniem obiektu. Po to tworzysz obiekt i publiczne metody, aby mieć do nich dostęp w funkcji Main. Jak napisał @some_ONE, jeden konstruktor załatwi sprawę też. Ale chyba nie wiem czy dobrze CIe zrozumiałem, chcesz skorzystać z pierwszego konstruktora, a potem z drugiego aby ustawić wartość "ogólna wielkość"?

Ps. Skoro masz w swojej klasie inne metody, to czemu nie stworzysz metody wypisującej(zwaracającej w postaci tekstu Twoich przypisanych wartości) tylko próbujesz wypisać do konsoli w konstruktorze? Coś chyba oszukujesz z tymi metodami kolego ;)

0

Dokładnie tak jak piszesz.
Chodzi o to, że jeśli użytkownik nie poda w konstruktorze "ogólna wielkość" to ma ona zostać ustawiona na tę właśnie wartość domyślną. Co najważniejsze ogólna wielkość nie może być modyfikowana po stworzeniu instancji Klasy.

W zadaniu mam najpierw stworzyć jeden konstruktor z tą ogólną wielkością, przetestować, a potem drugi konstruktor i tam mieć tą ogólną wielkość i też przetestować.

0

No to czyli źle Cie zrozumiałem. No ale dobra, to jeszcze raz,czego jeszcze nie wiesz i w czym masz problem.

0

Z tego co widzę to dużo nie wiem..

Jestem na takim etapie aktualnie:

class Program
    {
        static void Main(string[] args)
        {
            Klasa a = new Klasa();
            a.Pojemnosc = Double.Parse(Console.ReadLine());
            a.Ilosc = Double.Parse(Console.ReadLine());
            Klasa nowy = new Klasa(a.Pojemnosc,a.Ilosc); 

class Klasa
    {
        public double Pojemnosc;
        public double Ilosc;
        public readonly double Wielkosc;
        public Klasa(double pojemnosc, double ilosc, double wielkosc1 = 50)
        {
            Pojemnosc = pojemnosc;
            Ilosc = ilosc;
            Wielkosc = wielkosc1;
            Console.WriteLine(pojemnosc + "," + ilosc + "," + wielkosc1);
        }
}

Wczytuje, wyświetla wczytane dane + wartość domyślna wielkości ogólnej. Proszę o analizę. Nie wiem jak póki co zrobić ten warunek, że jeśli użytkownik nie poda w konstruktorze "wielkości ogólnej" to przypisuje wartość domyślną, czyli w tym przypadku 50. Czyli muszę zrobić tak jakby ta "wielkość ogólna" była wczytywana, ale jeśli nic nie ustawi to wartość domyślna.

0

Możesz to np. zrobić w ten sposób

 
public Klasa(double pojemnosc, double ilosc, double? wielkosc1 = 50)
        {
            Pojemnosc = pojemnosc;
            Ilosc = ilosc;
            Wielkosc = (double)wielkosc1;
            Console.WriteLine(pojemnosc + "," + ilosc + "," + wielkosc1);
        }
1

To musisz zobić obsługę dla użytkownika do wybrania opcji np (Przy wyborze Opcji 1 - podaje 3 wartości, a Opcji 2 - podaje 2 wartości) i w zależności od wczytanych danych wykorzystujesz stworzony przez siebie konstruktor. Tylko nie wiem co tworzysz obekt i do jego pól wczytujesz dane od użytkownika, a potem na podstawie pól z obiektu kolejny obiekt, nie lepiej użyć zmiennych?

0

Jakby to wyglądało na zmiennych?

1
 double a = Double.Parse(Console.ReadLine());
 double b = Double.Parse(Console.ReadLine());
/* Musisz sprawdzać czy użytkownik podał na pewno liczby (jest też metoda TryParse, która nie wyrzuci Ci exceptiona jeżeli nie uda się sparsować*/
            Klasa nowy = new Klasa(a, b); 
0

Nie wiedziałem że tak też się da, dlatego więc odwoływałem się bezpośrednio do pól. Jeszcze jedno pytanie, mam do stworzenia 3 konstruktory w jakiejś klasie. W pierwszym konstruktorze ustawiane są wartości np.marka, model, pojemnosc,** ilosc**, wielkosc ogólna. W drugim: marka, model, pojemnosc, ilosc. W trzecim: marka, model. Da się zrobić tak, aby nie powtarzać ustawiania wartości w tym przypadku np. marka i model, gdyż mają występować we wszystkich konstruktorach?

1
Frihu napisał(a):

Nie wiedziałem że tak też się da, dlatego więc odwoływałem się bezpośrednio do pól. Jeszcze jedno pytanie, mam do stworzenia 3 konstruktory w jakiejś klasie. W pierwszym konstruktorze ustawiane są wartości np.marka, model, pojemnosc,** ilosc**, wielkosc ogólna. W drugim: marka, model, pojemnosc, ilosc. W trzecim: marka, model. Da się zrobić tak, aby nie powtarzać ustawiania wartości w tym przypadku np. marka i model, gdyż mają występować we wszystkich konstruktorach?

class Klasa {
	string marka { get; set;}
	string model { get; set;}
	int pojemnosc { get; set;}
	int ilosc  { get; set;}
	int wielkosc_ogolna { get; set;}

public Klasa (string marka, string model, int pojemnosc, int ilosc, int wielkosc_ogolna)
{
	this.marka=marka;
	this.model=model;
	this.pojemnosc = pojemnosc;
	this.ilosc = ilosc;
	this.wielkosc_ogolna = wielkosc_ogolna;
}

public Klasa (string marka, string model, int pojemnosc, int ilosc)
{
	this.marka=marka;
	this.model=model;
	this.pojemnosc = pojemnosc;
	this.ilosc = ilosc;
}

public Klasa (string marka, string model)
{
	this.marka=marka;
	this.model=model;
}
}

EDIT @some_ONE
Czy dobrze zrozumiałem?

class Klasa {
	string marka { get; set;}
	string model { get; set;}
	int pojemnosc { get; set;}
	int ilosc  { get; set;}
	int wielkosc_ogolna { get; set;}

public Klasa (string marka, string model, int pojemnosc, int ilosc, int wielkosc_ogolna) : this
{
	this.marka=marka;
	this.model=model;
	this.pojemnosc = pojemnosc;
	this.ilosc = ilosc;
	this.wielkosc_ogolna = wielkosc_ogolna;
}

public Klasa (string marka, string model, int pojemnosc, int ilosc) : this(marka,model,pojemnosc,ilosc,0,0)
{ }

public Klasa (string marka, string model) : this(marka,model,"","",0,0)
{ }

}
0

Jak zrobić, aby np. Jeśli użytkownik nie wpisze żadnej wartości w wielkości ogólnej, kliknie enter to wyświetla mu się pierwszy konstruktor ( w którym jest wartość domyślna), jeśli wprowadzi jakąś wartość to wyświetla mu się drugi konstruktor:
Oczywiście wychodzi błąd ze stringiem, jak to pogodzić?

if (Convert.ToString(wielkosc_ogolna) == "")
            {
                Klasa nowy = new Klasa(pojemnosc, ilosc);
            }
            else
            {
                Klasa nowy2 = new Klasa(pojemnosc, ilosc, wielkosc_ogolna);
                
            }
1

Wczytujesz stringa, jeśli jest pusty to coś tam, a jeśli niepusty to dopiero wtedy konwertujesz na inta i robisz z nim coś tam innego.

0

Jak w programie głównym przypisać wartość pobieraną od użytkownika do parametru metody z innej klasy? Przy czym w tej klasie mam już klika konstruktorów?
przykład:

Klasa:

class Klasa2 
    {
        public void NieZwracam(int a)
        { coś robi }

public Klasa2(coś tam)
{
}

public Klasa2(coś tam)
{
}

public Klasa2(coś tam)
{
}
        

Część programu głównego:

            int a = Int32.Parse(Console.ReadLine());
            Klasa2 x = new Klasa2();
            x.NieZwracam(a); 

Oczywiście wywala błąd.

0
int a = Int32.Parse(Console.ReadLine());
Klasa2 x = new Klasa2();
x.NieZwracam(a);

Podaj treść błędu bo to nie powinno powodować żadnego.

0

"Odwołanie obiektu nie zostało ustawione na wystąpienie obiektu"
Oczywiście musiałem dodać konstruktor domyślny w Klasie, bo jak go nie dodałem to wywalał błąd że nie ma parametrów...

0

To błąd masz w innym miejscu.

http://ideone.com/alGkE7

1 użytkowników online, w tym zalogowanych: 0, gości: 1