Potrzebuję pomocy w C# - interfejsy

0

Witam serdecznie.
Mam następujące klasy
Pojazd: http://wklej.to/T9HNw
Car: http://wklej.to/N728a
Rower: http://wklej.to/6yTd1

oraz interfejs IPojazd: http://wklej.to/JmOdu

W klasie głownej Tworzę obiekty w następujący sposób:
http://wklej.to/3LSND

Moje pytanie brzmi: W jaki sposób mogę odwołać się w klasie głównej chociażby do składowej klasy Rower - TypLancucha ?
Próbowałem to zrobić poprzez rozszerzenie interfejsu IPojazd o interfejs IRower w którym znajdował się kod: int TypLancucha { get; set; }
jednak to nie zdało egzaminu. Z góry dzięki za pomoc.

0

Może opisz dokładnie co chcesz osiągnąć. Masz interfejs pojazd, ale czemu ma służyć klasa pojazd?

0

Klasa Pojazd jest ponad klasami Rower i Car. Chcąc zrozumieć mechanizmy dziedziczenia i polimorfizmu użyłem podobnego przykładu.
Mógłbym stworzyć "chyba" obiekt typu Pojazd i wtedy mogłoby pójść prościej jednak chciałbym aby program działał z użyciem interfejsu.
W klasie głównej przypisuję różne wartości do pól obiektów x, y oraz z, natomiast nie mogę wypisać na ekran pól dodatkowych z klasy Rower i Car (chodzi o pola typLancucha i rodzajPaliwa).

0
  1. Wklej kod.
  2. Nazewnictwo- nie baw sie w mieszanie angielskich i polskich nazw- Car i Rower. To bez sensu.
  3. Jesli dopiero uczysz sie o dziedziczeniu i polimorfizmie- zapomnij na jakis czas o interfejsach. Niepotrzebnie Ci to skomplikuje nauke.
0

Równie dobrze możesz implementować od razu interfejs Pojazd do klasy Car i Rower (zdecyduj się z nazewnictwem, polska czy angielska) lub zamiast użyć interfejsu zrobić klasę abstrakcyjną Pojazd i dziedziczyć z niej do samochodu i roweru. Nie widzę powodu aby używać klasy Pojazd razem z interfejsem o tej samej nazwie.

0

Wiedziałem, że ktoś się czepi nazewnictwa. Prosiłem o pomoc w tym szczególnym przypadku. Kody są wklejone - wystarczy tylko kliknąć w link..

0

Zwracam honor
Klasa pojazd

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Pojazd : IPojazd
    {
        private string _marka;
        private int _ileKol;
        private string _model;
        private int _cena;
        
        public string Marka
        {
            get
            {
                return _marka;
            }
            set
            {
                _marka = value;
            }
        }
        public int IleKol
        {
            get
            {
                return _ileKol;
            }
            set
            {
                _ileKol = value;
            }
        }
        public string Model
        {
            get
            {
                return _model;
            }
            set
            {
                _model = value;
            }
        }
        public int Cena
        {
            get
            {
                return _cena;
            }
            set
            {
                _cena = value;
            }
        }

        public Pojazd(string marka, string model)
        {
            Marka = marka;
            Model = model;
        }
        public Pojazd(string marka, string model, int ilekol, int cena)
        {
            Marka = marka;
            Model = model;
            IleKol = ilekol;
            Cena = cena;
        }
        public Pojazd() { }

        public virtual void Jedz()
        {
            System.Console.WriteLine("jedzie z klasy pojazd");
        }



    }
}
 

Klasa Rower

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Rower : Pojazd
    {
        private string _typLancucha;

        public string TypLancucha
        {
            get
            {
                return _typLancucha;
            }
            set
            {
                _typLancucha = value;
            }
        }

        public Rower(string marka, string model, int ileKol, int cena, string typLancucha)
            :base(marka, model, ileKol, cena)
        {
            TypLancucha = typLancucha;
        }

        public override void Jedz()
        {
            //base.Jedz();
            Console.WriteLine("z klasy rower");
        }



   
    }
}
 

Klasa Car

 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Car : Pojazd
    {
        private string _jakiePaliwo;

        public string JakiePaliwo 
        {
            get
            {
                return _jakiePaliwo;
            }
            set
            {
                _jakiePaliwo = value;
            }
        }

        public Car(string marka, string model, int ileKol, int cena, string jakiePaliwo)
            :base(marka, model, ileKol, cena)
        {
            JakiePaliwo = jakiePaliwo;
        }

        public override void Jedz()
        {
            //base.Jedz();
            Console.WriteLine("to napisane z klasy CAR");
        }

    
    }
}

Interfejs IPojazd

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    interface IPojazd
    {
        string Marka { get; set; }
        string Model { get; set; }
       
        int IleKol { get; set; }
        int Cena { get; set; }

        
        
        void Jedz();
    }
}
 

Klasa Main

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            IPojazd x = new Pojazd("audi", "model");
            System.Console.WriteLine("Marka: {0}, Model: {1}", x.Marka, x.Model);

            IPojazd y = new Car("audi", "a4", 4, 2200, "diesel");
            System.Console.WriteLine(y.Marka + y.Model + y.IleKol + y.Cena);

            IPojazd z = new Rower("romet", "c40", 2, 200, "prosty");
            System.Console.WriteLine(z.Marka + z.Model + z.IleKol + z.Cena);
            //System.Console.WriteLine(z.TypLancucha);   // <-------------------------   chcę aby ta linijka kodu mogła się wykonać
            System.Console.ReadLine();                  
        }
    }
} 
0

To Ci się kompiluje? Jaki masz komunikat błędu?

0

Nie mam żadnego błędu. Błąd pojawia się przy próbie odniesienia do z.typLancucha lub y.jakiePaliwo. Po wpisaniu "z." nie ma tam do wyboru pola typLancucha. Domyślam się, że gdzieś muszę dodać get bądź set. Myślałem, że aby to osiągnąć wystarczy informacja w kodzie, że klasa Car i Rower są pod klasą Pojazd.

0

Próbowałeś dodać this. przed przypisaniem w konstruktorze? Na przykład:

 
public Car(string marka, string model, int ileKol, int cena, string jakiePaliwo)
            :base(marka, model, ileKol, cena)
        {
            this.JakiePaliwo = jakiePaliwo;
        }

0

Tak próbowałem. Jednak w dalszym ciągu nie zauważyłem zmiany.

0

Tworząc obiekt typu "Pojazd" nie ma najmniejszego problemu z odniesieniem się do tych dwóch pól. Jednak chcąc rozwiązać to za pomocą interfejsu - nie wiem gdzie powinienem uzupełnić brakującą (ew. źle napisaną) część kodu.

1

Jak chcesz się odwołać do TypLancucha jeśli w interfejsie go nie ma? Tworzysz obiekt IPojazd i do jego pól możesz się odwołać.

0

Problem leży tutaj:

 
IPojazd z = new Rower("romet", "c40", 2, 200, "prosty");

Tworzysz obiekt z bazujący na interfejsie, który nie jest rozszerzony o typ łańcucha. Tak samo z samochodem.

Ten kod rozwiąże sprawę.

 
Rower z = new Rower("romet", "c40", 2, 200, "prosty");
0

Znalazłem to rozwiązanie :) Naprawdę nie ma możliwości by w jakiś sposób rozszerzyć mój interfejs aby to zadziałało w sposób jaki chciałem? Nie twierdzę, że jest to rozwiązanie właściwe lecz pytam z czystej ciekawości.

0

Teoretycznie mógłbyś rozszerzyć interfejs o typ łańcucha ale wtedy nie będziesz mógł wykorzystać go do stworzenia samochodu. Interfejsy nie są stworzone do tego aby były elastyczne tylko aby wymuszały wcześniej ustaloną strukturę w klasach potomnych.

0

Ok, dzięki za pomoc. Najwyraźniej brakowało mi wiedzy którą od Ciebie otrzymałem w ostatnim poście.

3

Pomyśl o tym w ten sposób: Czy możesz założyć że każdy pojazd (bo interfejs IPojazd definiuje dowolny pojazd) ma łańcuch - pewnie wiele tak ale nie wszytkie. Odwołując się do obiektu poprzez interfejs kótry on implementuje masz dostęp tylko do tego co jest zawarte w interfejsie. Jeśli chcesz odwołać się do łańcucha przez pojazd to może zdarzyć się sytuacja, że będziesz chciał się odwołac do łańcucha np w taczce, albo promie kosmicznym.

Co to implementacji interfejsu - klasa Pojazd powinna być klasą abstrakcyjną - analogicznie: czy istnieje coś co jest po prostu pojazdem , coś co może być jednocześnie rowerem, taczką, promem kosmicznym czy samochodem ? Nie można utworzyć obiektu który jest jednocześnie wszystkim dlaetgo powinien być on klasą abstarkcyjną (byt będący na raz wszytskimi wymienionymi rzeczami też jest raczej abstarkcyjny ;-) )po której dziedziczą już konkretne klasy.

0

Jedna odpowiedź i o ile więcej człowiek wie :) Dzięki W2K Tobie również.

1

A wystarczyłoby, żebyś przeciążył metodę ToString w swoich klasach, i mógłbyś łatwo wyświetlić wszystkie informacje jakie chcesz, np. w klasie Rower:

 
public override ToString()
{
    return string.Format("Marka: {0} model: {1}: łańcuch: {2}", this.Marka, this.Model, this.TypLancucha);
}

użycie:

IPojazd z = new Rower("romet", "c40", 2, 200, "prosty");
Console.WriteLine(z);

Jeszcze taka uwaga - używaj automatycznych właściwości, pisanie:

private string _marka;
 
        public string Marka
        {
            get
            {
                return _marka;
            }
            set
            {
                _marka = value;
            }
        }

zamiast po prostu:

public string Marka { get; private set; } 

to jakiś masochizm.

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