dlaczego rzutowanie się nie udaje

0

Mam dwie klasy: klasaA i klasaB, przy czym klasaB dziedziczy z klasaA.
Następnie deklaruję obiekt klasy A.

klasaA k1 = new klasaA();

i chcę zrobić rzutowanie:

klasaB btest= k1;

to wyskakuje błąd

Error 2 Cannot implicitly convert type 'usingdll.Form1.klasaA' to 'usingdll.Form1.klasaB'. An explicit conversion exists (are you missing a cast?) E:\visual studio projects\projects\mydll\usingdll\Form1.cs 130 30 usingdll

co w moim rozumieniu znaczy, że potrzebne jest jawne (explicit) rzutowanie.
A kiedy rzutuję jawnie:

klasaB btest= (klasaB)k1;

to kompiluje się kod, ale kiedy dochodzi do linijki rzutowania, występuje
"błąd rzutowania".
Czy ktoś mi wytłumaczy co się dzieje wewnątrz takiego rzutowania, że się nie udaje?
Jak to rzutowanie przebiega wewnątrz klasy? Bardzo proszę o odpowiedzi.

0

Znalazłem coś takiego:

public class A
{
    public A() { }
}

public class B : A
{
    public B() { }
}

The new class—the derived class—then gains all the non-private data and behavior of the base class in addition to any other data or behaviors it defines for itself. The new class then has two effective types: the type of the new class and the type of the class it inherits.

In the example above, class B is effectively both B and A. When you access a B object, you can use the cast operation to convert it to an A object. The B object is not changed by the cast, but your view of the B object becomes restricted to A's data and behaviors. After casting a B to an A, that A can be cast back to a B. Not all instances of A can be cast to B—just those that are actually instances of B. If you access class B as a B type, you get both the class A and class B data and behaviors. The ability for an object to represent more than one type is called polymorphism.

Z tego można zrozumieć, że klasa dziedzicząca B jest zarówno klasą B i A, ale klasa A jest tylko klasą A. Kiedy się odwołuje do obiektu klasy B to można go przekształcić na obiekt klasy A. Obiekt klasy B się nie zmienia pod wpływem rzutowania, ale zmienia się widok, który zostaje ograniczony do pokazywania tylko danych obiektu klasy A i jego zachowań. Po rzutowaniu B na A można rzutować A na B, ale nie wszystkie instancje A mogą być rzutowane na B. Mogą tylko te, które są instancjami B. Kiedy się odwołuje do klasy B jako typu B dostaje się dane i zachowania klasy A i B. Zdolność obiektu do reprezentowania wiecej niz jednego typu jest nazywana polimorfizmem.

1

Mówiąc krótko: możesz rzutować klasę B na klasę A, ponieważ klasa B zawiera wszystko co ma klasa A + to co rozszerza. W drugą stronę to nie przejdzie, ponieważ klasa A nie posiada elementów klasy B i mógłbyś chcieć odwołać się do nieistniejącej metody czy pola.

Ps. Czemu piszecie wszystko w komentarzach?

0

To jest raczej pytanie o bebechy samego runtime, bo to on rozpoznaje, które bajty w pamięci należą do obiektu której klasy, a na podstawie kodu programu wie, co z nimi można zrobić.

W zasadzie nie ma sensu nigdy dokonywać takiego rzutowania. Jeśli rodzi się taka potrzeba, to znaczy, że projekt aplikacji jest zły - być może trzeba np. zastąpić dziedziczenie jakąś kompozycją.

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