Java - rzutowanie

0

Witam i życzę świetnego dnia wszystkim !

Moje pytanie odnosi się do tego czy dobrze zrozumiałem temat rzutowania objektów (pomijam to rzutowanie typów prostych).

1.Rzutowanie obiektu na inny typ służy do zmienienia funkcjonalności(dostęp do metod/obiektów/zmiennych typu rzutowanego) obiektu.

2.Rzutowanie przeprowadza z pomocą zmiennej pomocnej takiego samego typuTyp_123 co rzutowanieTyp_123.
Inny_typ zmienna_rzutowana - new Inny_typ() ;
Typ_123 zmienna_pomocicza = (Typ_123)zmienna_rzutowana ;

  1. Typ_123 musi dziczyć Inny_typ - bez dziedziczenia nie ma rzutowania bo kompilatorr wyrzuci wyjątek ponieważ będzie się odwoływał obiektów/metod do których nie ma dostępu bo ich nie odziedziczył ---> // class Typ_123 extends Inny_typ

  2. Inny_typ zmienna_pomocicza traci referencje (dostęp) do metod/obiektów.zmiennych swojego typu ( Inny_typ ) których nie ma w typie rzutowanym np:

Inny_typ ---> (a=3 , b=5 , c=11)
Typ_123 ---> (a,c)
Typ_123 zmienna_pomocicza = (Typ_123)zmienna_rzutowana - traci dostep do b - czyli a=3 c=11

co w przypadku kiedy:
Inny_typ ---> (a=3 , b=5 , c=11)
Typ_123 ---> (a=22,c=55)
Typ_123 zmienna_pomocicza = (Typ_123)zmienna_rzutowana - traci dostep do b - czyli a=22 c=55 ???????????

PS.
Pytania :
Poza szczególnymi przypadkami jakie praktyczne zastosowanie może mieć rzutowanie?

Pozdrawiam

0

Mieszasz straszliwie ;]
Przeczytaj to:
Rzutowanie w górę, w jakim celu ?
bo pytanie tam było dość podobne.

0
Shalom napisał(a):

Mieszasz straszliwie ;]
Przeczytaj to:
Rzutowanie w górę, w jakim celu ?
bo pytanie tam było dość podobne.

Przeczytałem wcale mi to nie pomogło..."Mieszaszam" tzn że zle pisze czy że nie zrozumiałeś co pisze?

PS.
Możecie mnie nie kierować na inne watki bo temat sprecyzowałem "czy dobrze rozumiem"

1

Zasadniczo niewiele z tego co napisałeś jest poprawnie ;]

  1. Rzutowanie nie zmienia funkcjonalności obiektu, tylko zmienia tak jakby "widok" tego obiektu. Obiekt ma pewne funkcjonalności i już. Ale wyobraź sobie że chcesz komuś zwrócic pewien strasznie skomplikowany obiekt. Ten ktoś wcale nie potrzebuje o tym wiedzieć. On potrzebuje tylko wiedzieć że ten obiekt ma jakąś konkretną funkcjonalność. To się nazywa "zasadą separacji interfejsów" polecam się z nią zapoznać.
  2. W pewnym sensie tak, ale zauważ że w Javie wcale nie tworzysz w ten sposób "nowego obiektu" czy też "nowej zmiennej". To jest tylko referencja/wskaźnik do obiektu. Obiekt cały czas jest ten sam!
  3. Tak, bo java to nie C++. W C++ możesz rzutować wszystko na wszystko, możesz rzutować nawet kupę nicnieznaczących bajtów na obiekty :P Ale java sprawdza czy to co chcesz zrobić ma sens.
  4. Tego akurat nie rozumiem. To co tam podajesz to są domyślne wartości pól czy co? Ty chyba w ogóle nie rozumiesz co się tam dzieje ;] Materiał poglądowy:
class A{
  private final int pole1 = 1;
  public void metoda1(){
  }
}

class B extends A{
  private final int pole2 = 2;
  public void metoda2(){
  }
}

I teraz jeśli weźmiemy sobie obiekt klasy B i przypiszemy go do referencji do A:

A alamakota = new B();

To efekt będzie taki ze na obiekcie alamakota nie możemy wywołać metody metoda2() bo "jej nie widać". Tak samo "nie widać" pola pole2. Ale wszystko inne pozostaje bez zmian. W szczególności musisz sobie uświadomić że klasa B tak "naprawdę" wygląda tak:

class B{
  private final int pole1 = 1;
  private final int pole2 = 2;

  public void metoda1(){
  }

  public void metoda2(){
  }
}
1

Rzutowanie zmienia interfejs, nie zmienia zachowania obiektu. Jeżeli jakiś obiekt ma metodę m(), która jest zdefiniowana w jego klasie i w N klasach bazowych (wyższych) to obojętnie na którą klasę bazową go zrzutujesz to zawsze po wywołaniu m() stanie się dokładnie to samo. Dzieje się tak dlatego, że w Javie wszystkie funkcje są wirtualne.

Na Wikipedii jest nawet fajny przykład:

// from file PolymorphismExample.java
package org.wikipedia.examples;
import java.util.*;
 
public class PolymorphismExample {
 
        public interface Animal {
                public String talk();
        }
 
        public  class Dog implements Animal {
                @Override
                public String talk() {
                        return "Dog says Woof! Woof!";
                }
        }
 
        public  class Cat implements Animal {
                @Override
                public String talk() {
                        return "Cat says Meow!";
                }
        }
 
        public static void main(String[] args) {
                ArrayList<Animal> animals = new ArrayList<>();
                animals.add(new Cat());
                animals.add(new Dog());
 
                for (Animal a : animals) {
                        System.out.println(a.talk());
                }
        }
}
 
// When you run this, the output is:
// Cat says Meow!
// Dog says Woof! Woof!

Pola publiczne są za to zależne od tego na co zrzutujesz obiekt, tzn pola publiczne nie są nadpisywane jak metody, a tylko przesłaniane, czyli jeśli mamy:

class A {
int field;
}
class B extends A {
int field;
}

To jeśli mamy obiekt klasy B, to:

  • jeśli zrzutujemy go na A, to możemy dobrać się bezpośrednio tylko do field zadeklarowanego w klasie A,
  • jeśli zrzutujemy go na B, to możemy dobrać się bezpośrednio tylko do field zadeklarowanego w klasie B,

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