Dziedziczenie i interfejsy

Odpowiedz Nowy wątek
2015-02-19 20:36
PolskaGola
0

Witam! Mam pytanie odnośnie interfejsów i dziedziczenia. Załóżmy, że mamy taka sytuację, że mamy 2 klasy, powiedzmy Car i Tiny, Tiny dziedziczy po Car, obie klasy implementują interfejs "IDriveable", który implementuje metodę "goForward()". Teraz tworze statyczną funkcję w tym samym pliku co funkcja główna "main", która jako argument pobiera argument typu "IDriveable", teraz jak przekazuję obiekt typu "Car" no to wykonuje się dla Car, natomiast jak podam typu Tiny to wykonuje się "goForward()" dla typu Tiny. Czyli polimorfizm dla interfejsu działa. Tylko teraz jak zdefiniuje funkcję, która jako argument przyjmuję typ "Car", i będę w niej wykonywał funkcje z interfejsu:

public static void checker(Car car)
{
     car.goForward();
} 

jak podam obiekt typu "Car", to wykona się dla typu Car, natomiast jak podaje obiekt typu "Tiny" ( który dziedziczy po Car, i implementuje ten sam interfejs) to polimorfizm już nie działa, i funkcja wykonuje się jak dla typu Car. No i teraz pytanie, czy w C# już tak po prostu jest? Dla typu Car nie uruchomię funkcji z interfejsu dla typu Tiny( tylko uruchomię oryginał)? I gdyby chciał żeby działało dla Tiny to bym musiał użyć słówka virtual i robić zwykły polimorfizm? Próbuję to jakoś zrozumieć..

Pozostało 580 znaków

2015-02-19 20:40
1
public static void checker(IDriveable drivable)
{
     drivable.goForward();
} 

W C# masz kilka koncepcji:

virtual void metoda() {} // Tworzy NOWĄ metodę wirtualną z daną implementacją (jeszcze raz podkreślam nową, jeśli w klasie dziedziczącej napiszesz new virtual to dostaniesz drugą kopię i będzie to inna metoda wirtualna o tej samej nazwie)
override void metoda() {} // nadpisuje metodę wirtualną z klasy bazowej
abstract void metoda() {} // Tworzy metodę wirtualną bez podawania implementacji - tj. musisz ją nadpisać

//w interfejsie:
void metoda(); // dokładnie tak jak abstract, z minimum dwoma ważnymi wyjątkami - dla struktur nie koniecznie musisz dostać V-table jeśli nie używasz bezpośrednio interfejsu ORAZ możesz implementować więcej niż 1 interfejs w klasie

Jakkolwiek to nie zrobisz szablon wygląda zawsze tak samo:

KlasaBazowa o = new KlasaPochodna1();
// i operujesz na klasie/interfejsie bazowym, a nie na konkretnej implementacji interfejsu.
// jesli chcialbys sprawdzic czy dana implementacja interfejsu jest danej klasy:
bool jestKlasaPochodna1 = o is KlasaPochodna1;

// chcesz rzutowac, bez rzucania wyjatkiem w przypadku gdy sie nie da (dostaniesz null jesli nie jest):
KlasaPochodna1 p = o as KlasaPochodna1;

// chcesz rzutowac, ale jak sie nie uda to rzuc wyjatkiem:
KlasaPochodna1 p2 = (KlasaPochodna1)o;

░█░█░█░█░█░█░█░█░█░█░█░
edytowany 1x, ostatnio: krwq, 2015-02-19 20:50

Pozostało 580 znaków

2015-02-19 20:49
PolskaGola
0

no napisałem tak w pierwszej wersji, potem pytam o drugą wersję dlaczego tak nie może być skoro dziedziczy Tiny po Car i implementują ten sam interfejs.....Po prostu tak już jest w C# i żeby tego użyć muszę robić zwykły polimorfizm wtedy?

zobacz czy po edycji postu juz odpowiada na Twoje pytanie. Nie rozumiem Twojego pytania. - krwq 2015-02-19 20:52

Pozostało 580 znaków

2015-02-19 21:02
PolskaGola
0

Wygląda to tak :
Klasa Car

 class Car : IDriveable
        {
            public void goUp() // z interfejsu
            {
                Console.WriteLine("Go with Car up");
            }
        }

        class Tiny : Car, IDriveable
        {
            public new void goUp() // z interfejsu
            {
                Console.WriteLine("Go with Tiny up");
            }
        }

        public interface IDriveable
        {
            void goUp();
        }

        //tam gdzie main
        public static void checker(Car id)
        {
            id.goUp();
        }

        public static void Main(string[] args)
        {
            Tiny tiny = new Tiny();
            checker(tiny);
        }

i moje pytanie dlaczego wykona się goUp dla Car, a nie dla Tiny ( skoro Tiny dziedziczy po Car i implementuje ten sam interfejs) czy tak jest po prostu w C# w związku z interfejsami? Bo wiem, że jesli argument w funkcji checker byłby IDriveable to wykonałoby się dla Tiny.

Pozostało 580 znaków

2015-02-19 21:08
0

Zobacz co robi słówko "new" tutaj: public new void goUp().


░█░█░█░█░█░█░█░█░█░█░█░

Pozostało 580 znaków

2015-02-19 21:25
1

To nie ma związku z interfejsami tylko z tym, że metoda Car.goUp nie jest wirtualna, więc niby jak mogłaby być wywołana jej wersja z klasy dziedziczącej?


"HUMAN BEINGS MAKE LIFE SO INTERESTING. DO YOU KNOW, THAT IN A UNIVERSE SO FULL OF WONDERS, THEY HAVE MANAGED TO INVENT BOREDOM."

Pozostało 580 znaków

2015-02-19 22:11
dsfg
0
somekind napisał(a):

metoda Car.goUp nie jest wirtualna, więc niby jak mogłaby być wywołana jej wersja z klasy dziedziczącej?

pewnie spaczenie z javy gdzie wszystkie metody są domyślnie wirtualne - swoją drogą mimo że nie lubię javy to wydaje mi się że to akurat bardziej przyjazne programiście podejście

@PolskaGola

Tiny nie musi już jawnie deklarować implementację IDriveable skoro już dziedziczy z Car który implementuje ten interfejs

Pozostało 580 znaków

2015-02-19 22:21
PolskaGola
0

no tylko ze jak nie dam w Tiny : IDriveable to nawet jak w checker est argument typu IDriveable i podam mu Tiny to wykonuje jako Car...(tzn dla klasy nadrzednej wykonuje goUp())

Pozostało 580 znaków

2015-02-19 22:31
0

Zrób tą metodę goUp() w klasie Car jako virtual, w klasie Tiny daj jako override i wywal to niepotrzebne dziedziczenie po IDriveable i będzie działać tak jak chcesz żeby działało.

Pozostało 580 znaków

2015-02-19 22:37
PolskaGola
0

Ja wiem, że tak może działać po prostu pytałem czemu to nie działa razem z interfejsem i tyle.

Pozostało 580 znaków

2015-02-19 22:41
0

To dziedziczenie po interfejsie w klasie Tiny akurat niczego nie zmienia.

http://stackoverflow.com/ques[...]-usage-virtualoverride-vs-new
2 odpowiedź, masz wyjaśnione.

//Ok, chyba chodziło Ci o co innego.
https://msdn.microsoft.com/en[...]ry/aa664593%28v=vs.71%29.aspx

edytowany 3x, ostatnio: some_ONE, 2015-02-20 00:21

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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