rzutowanie obiektów

Odpowiedz Nowy wątek
2011-10-25 21:20
0
public class A {
    public void x() {//jakis kod};
}
public class B extends A{
    public void x() {
        //jakis kod
    }

    public void y() {
        //jakis kod
    }
}
A obiekt = new B();
        obiekt.x();
        obiekt.y(); // to nie zadziała bo klasa A nie zna metody y();

W takim przypadku przydaje się rzutowanie żeby 'obiekt' otrzymał dostęp do metody y(). Moje pytanie jest takie, czy są jakieś inne przypadki kiedy trzeba rzutować obiekty i czy rzutować można tylko na typy której dany obiekt tą klasę dziedziczy?

Pozostało 580 znaków

2011-10-25 23:42
0
lofi napisał(a)

Moje pytanie jest takie, czy są jakieś inne przypadki kiedy trzeba rzutować obiekty
W ogóle zamiast rzutować, powinno się wykorzystywać polimorfizm.

lofi napisał(a)

i czy rzutować można tylko na typy której dany obiekt tą klasę dziedziczy?
Jaki byłby sens rzutowania obiektu na klasę, której instancją on być nie może...

Pozostało 580 znaków

2011-10-26 00:59
0

Zauważ, że pierwsze niejawne rzutowanie masz już kiedy do referencyjnej zmiennej A przypisujesz referencję obiektu B. Ponieważ rzutowanie takie tylko zawęża interfejs, a obiekt potomny wobec rodzica spełnia zawsze relację "jest", to takie rzutowanie masz z automatu. W drugą stronę musisz jawnie sprawdzić relację "is" do czego służy operator instanceof lub metoda isInstance(). Wtedy do dyspozycji jest cała lista typów potomnych, od typu, którego reprezentuje referencja, a aż do typu mającego identyczny plik Class<?>. Czasem bezpieczniej i lepiej wygląda rzutowanie za pomocą metody Class.cast(Object o), której zapis bardziej przypomina rzutowanie w C++.

Innym czasem przydatnym rodzajem rzutowania jest jawne rzutowanie referencji obiektu jakiejś klasy na interfejs (którego ta klasa implementuje), albo bardziej zawężony interfejs któregoś rodzica. Robi się tak po to aby ktoś kto taką referencję dostanie nie próbował wywoływać metod obiektu konkretnego, a jedynie te z interfejsu. Bardzo rzadko bywa też potrzeba rzutowania z jednego interfejsu na inny mając w rzeczywistości obiekt konkretny, który implementuje oba. Jednak takie coś świadczy najczęściej o złym projekcie - szczególnie kiedy oba interfejsy nie mają zależności w pionie (tzn. jako kolejnych rozszerzeń interfejsu).


Jeżeli ktoś komuś coś, ewentualnie nikt nikomu nic, to właściwie po co...?

Pozostało 580 znaków

2011-10-26 01:54
0

Jeśli spróbujesz rzutować sobie pomiędzy typami które do siebie nie pasują to dostaniesz ClassCastException ;)
Przy czym sam fakt że musisz coś rzutować może (acz nie musi) oznaczać że coś w projekcie jest nie tak.


Masz problem? Pisz na forum, nie do mnie. Nie masz problemów? Kup komputer...
Jak typ, na który chcesz rzutować nie pasuje do typu, z którego rzutujesz, to to w ogóle nie da się rzutować... już kompilator Ci to wypomni - Kerai 2011-10-26 10:21
Jasne, ale jak rzutujesz niepoprawnie "w górę" to kompilator ci nic nie wypomni :P - Shalom 2011-10-26 14:48

Pozostało 580 znaków

2011-10-26 18:59
0

Hmmm, a jeśli o "inne przypadki" chodzi... chyba najklasyczniejszym przypadkiem, gdzie to rzutowanie jest, to by była equals

public class Foo {

    private int p,q;

    public Foo() { /* ... */ }

    @Override
    public int hashCode() {  return /* ... */; }

    @Override
    public boolean equals(Object value) {
        if (value == null) { return false; }

        if (getClass() != value.getClass()) { return false; }

        final Foo foo = (Foo)value;

        if (this.p != foo.p) { return false; }
        if (this.q != foo.q) { return false; }
        return true;
    }

}

Nie kojarzę jakiegoś innego popularnego idiomu, który powszechny jest - coś mi się Swing kojarzy, że tam też by wyszukał różne akcje, gdzie innej rady nie ma.

Tak na marginesie podobno zawsze warto na początku equals sprawdzić równość this == value, dzięki czemu wiadomo, że porównujemy obiekt z nim samym. - Olamagato 2011-10-26 21:22
fakt, nie cierpie equalsów w rękach pisać, zawsze się gdzieś trzasnę za pierwszym podejściem. btw - ten to jest przeformatowany wygenerowany przez NetBeansa ;) - Ranides 2011-10-27 07:21

Pozostało 580 znaków

2011-10-26 19:20
bo
0

Dobrze Ci się kojarzy. Często źródło zdarzenia otrzymane przez ev.getSource() - jest ono typu Object - jest rzutowane na konkretny komponent.

Pozostało 580 znaków

2011-10-26 19:49
0

O to to... jak mnie to wkurzało... Nawet się wściekłem i zrobiłem takie cuś (udało się wygrzebać), co po mocnym okrojeniu wyglądałoby tak:

public abstract class QListSelectionListener<Element> implements ListSelectionListener {

    public abstract boolean onSelect(ListSelectionEvent event, int index, Element value);

    public abstract boolean onClear(ListSelectionEvent event);

    public QListSelectionListener(JList list) {
        this.owner = list;
    }

    @Override
    public void valueChanged(ListSelectionEvent event) {
        if( event.getValueIsAdjusting() ) { return; }
        DefaultListSelectionModel selection = (DefaultListSelectionModel)event.getSource();
        int index = selection.getAnchorSelectionIndex();
        if(-1 == index) {
            onClear(event);
        } else {
            onSelect(event, index, (Element)owner.getModel().getElementAt(index) );
        }
    }

    private final JList owner;

}

coby rzutowań i zaznaczenia od zaznaczenia sobie oszczędzić w handlerach... a potem się dowiedziałem, co to jest "unchecked cast" ... i że cały ten kod to można kotu w zad wsadzić. I całe to naklepane dzieło postanowiłem wyprzeć z pamięci. Nie udało się :D Na ile związek z tematem? Głupia obsługa zaznaczenia wiersza - i i dwa rzutowania pod rząd, żeby pobrać model, a potem żeby sobie wartość tego wiersza zgarnąć... bo ani event, ani modele nie mają pojęcia o tym, co trzymają. Więc tak - niestety dobrze zaprojektowany program jeśli będzie miał GUI, to rzutowaniami będzie tłukł ostro ;)

Ktoś coś wie o tym, czy jest w planach to kiedyś zgenerics'ować tak jak collections? Nie jestem na bieżąco.

No i ten potworek pokazuje też, że można - jak się jest durniem - napisać kod, który robi totalnie idiotyczne rzutowania (np Number na ImageIcon ;)) - i ani kompilator, ani runtime słowem nie piśnie. Uważać z rzutowaniami człowiek musi...

edytowany 2x, ostatnio: Ranides, 2011-10-26 19:54

Pozostało 580 znaków

2011-10-26 19:56
0

Ranides:
Za rok, dwa JavaFX 2 stanie się standardem i zastąpi wysłużonego Swinga.


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.

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