Tworzenie obiektu - jakiego jest typu?

0

Witam. Mam pytanie i to pewnie nie jest dobry dział, ale po usunięciu Newbie nie wiem gdzie zapytać.
Przykładowo mamy klasę A dziedziczącą po klasie B. Teraz tworzymy obiekt:

A z = new B ();

Jak teraz wygląda obiekt z? Deklaracja jest typu A a inicjalizacja typu B, dlaczego tak?

1

Żeby móc gromadzić obiekty podobne do siebie w tablicach/listach i wykonywać na nich operacje wspólne dla wszystkich obiektów.
Np. masz instancje klas Okrąg i Trójkąt, które dziedziczą po klasie Geometria. Każdy obiekt jest rysowany inaczej, więc przeładowuje sobie wirtualną metodę Rysuj.
Jak dodasz wszystkie okręgi i trójkąty do listy typu Geometria, będziesz mógł w jednej pętli je narysować.

Pewnie ktoś się będzie spierał, że do samego rysowania wystarczy implementować po interfejs, ale idea podobna ;)

Obiekty, które dziedziczą jakieś pola można łatwiej przekazywać innym obiektom/metodom, których działanie chcemy modyfikować takimi "modułami".

0

Po pierwsze z nie jest obiektem, to jest referencja, czyli rodzaj wizytówki, w której masz lokalizację obiektu i jego typ. Więc Twoja wizytówka zawiera poprawną lokalizację obiektu, ale niezgody typ z rzeczywistym (w sensie nie taki sam). Rzeczywisty obiekt ma typ B, który jest rozszerzeniem typu A, czyli można by zapisać, że B = A + coś dodanego, czyli z choć ma inny typ może być traktowany jako A.

Bardziej przejrzyście to można wytłumaczyć gdyby A to była klasa Osoba ze składowymi imię, nazwisko i data urodzenia, a B to klasa Lekarz, która jest wyprowadzona z klasy Osoba. Możesz utworzyć referencje do konkretnego lekarza typu Osoba, bo przecież każdy lekarz jest osobą. Wtedy taka referencja umożliwiałaby wykonać wszystkie operacje na jakimś lekarzu jak na osobie., typu podaj imię, nazwisko czy datę urodzenia. Ale gdy potrzebowałbyś uzyskać za pomocą tej referencji jakiś informacji o lekarzu, to musiałbyś zrzutować referencję na klasę Lekarz..

0

No właśnie chyba nie na odwrót, bo widziałem taki przykład i klasa dziedzicząca była przy deklaracji

3

Jeśli:

class A{
}
class B: A {
}

to możesz:

A z = new B();
A z = new A();
B z = new B();

ale nie możesz

B z = new A();

Dziedziczenie rozszerza rozumienie zgodności typów, teraz referencji z o typie A, możesz przypisać obiekt typu A jak i każdy typ, który został wyprowadzony z A. Każdej referencji do osoby możesz przypisać obiekt klasy Osoba jak i klasy Lekarz, Górnik itd. Ale nie można do referencji typu Lekarz przypisać obiektu typu Osoba, bo wtedy Twoja wizytówka zawierałaby informację, że obiekt to lekarz, który powinien mieć składowe np. specjalizacja, data zatrudnienia itd., których Twój rzeczywisty obiekt ma.

0

Dzięki za wyjaśnienia, ale mimo wszystko jest ktoś w stanie podać przykładowy kod? Teoretycznie niby rozumiem ale zawsze łatwiej mi coś zrozumieć bazując na kodzie

0

To jest rzutowanie referencji na klasę bazową.
Czyli obiekt ob ma dostęp tylko do składowych klasy bazowej . W przypadku wirtualnych składowych jest inaczej.
Przykład niżej .

using System;


namespace ConsoleApp5
{
    class Program
    {
        static void Main(string[] args)
        {
           A ob = new B();
            Type tp = ob.GetType();
            Console.WriteLine(tp.BaseType.Name);
            Console.WriteLine(tp.Name);
            ob.MetodaA(); // na konsoli - klasa A
            ob.MetodaX(); // na konsoli - klasa B

        }
    }
    class A
    {
        public void MetodaA() { Console.WriteLine("klasa A"); }
        public virtual void MetodaX() { Console.WriteLine("klasa A"); }
    }

    class B : A
    {
        public new void MetodaA() { Console.WriteLine("klasa B"); }
        public override void MetodaX() { Console.WriteLine("klasa B");}
    }
}
0
using System;

class Person{
  public String name;

  public Person(){
    name = "";
  }

  public Person(String name){
    this.name = name; 
  }
}

class Worker: Person{
  public String profession;

  public Worker(String name, String profession):base(name){
    this.profession = profession;
  }
}

class MainClass {
  public static void Main (string[] args) {
    Person me = new Person("Ludek");
    Person speedyGonzales = new Worker("Kazek","driver");
    //Obie referencja dają możliwość odwołania się do pola name 
    Console.WriteLine(me.name);
    Console.WriteLine(speedyGonzales.name);
    //tutaj kicha, referencja `me` zawiera obiekt, który nie ma pola profession
    //Console.WriteLine(me.profession);
    
    //referencję `speedyGonzales` można przekształcić na typ
    //obiektu, czyli Worker, i wtedy można odwołać się do pola profession
    Console.WriteLine(((Worker)speedyGonzales).profession);
  }
}
0

Jest jeden obiekt , który ma cały czas ten sam typ .
tylko istnieją dwa różne odwołania od tego samego obiektu .
Zmienna typu Człowiek ma dostęp tylko do składowych typu Człowiek a zmienna typu Mezczyzna ma dostęp do składowych z obydwu klas , chyba że jakieś składowe zostały ukryte, przesłonięte albo są prywatne.

using System;
namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
                Mezczyzna os1 = new Mezczyzna();
                Człowiek os2 = os1;
                os2.Imie = "Jan";
                Console.WriteLine(os1.Imie);

                Console.WriteLine( os1 ==  os2);      
        }
    }
    class Człowiek
    {
        public string Imie { get; set; }
    }

    class Mezczyzna : Człowiek
    {
        
    }
}
0

Dzięki panowie!! Na razie jestem w trasie, ale jak wrócę od razu sobie przestudiuje te Wasze przykłady

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