Wpis z mikrobloga

class A extends Z {}
class B extends Z {}
class C extends Z {}

void m1 (A a);
void m1 (B b);
void m1 (C c);

Mam obiekt z typu Z który może być A B lub C. Nie wiem jakiego będzie typu. Jak najsprawniej zrzutować ten obiekt do typu pierwotnego i przekazać go do metody m1? Potrójny IF gdzie będę po kolei sprawdzał instanceof i wtedy rzutował na właściwy typ? A może stworzyć 3 metody m1-A, m1-B, m1-C i dynamicznie konstruować nazwę właściwej metody na zasadzie "m1-" + z.getClass().getName() i przy użyciu refleksji wywołać taką metodę?

Może jest jeszcze jakiś lepszy sposób?

#java #programowanie
  • 15
  • Odpowiedz
  • Otrzymuj powiadomienia
    o nowych komentarzach

@Czesiowcy: @Kresse: @jcollier: Mam taką hierarchię klas. Parser zwraca mi Expression które złożone jest z obiektów z ostatniej linii. Wszystkie te obiekty w czasie parsowania są zapisywane do zmiennej Expression ex więc dostają typ bazowy. Musi tak być, bo nie wiem co konkretnie zwróci parser, to może być każdy z obiektów.

Próbuję zaimplementować na tym wzorzec Visitor który będzie rekurencyjnie analizować Expression. Z uwagi na
M.....3 - @Czesiowcy: @Kresse: @jcollier: Mam taką hierarchię klas. Parser zwraca mi ...

źródło: comment_LDENNBj5uxCyOdhNWHGBHdWZx2Dy8qVI.jpg

Pobierz
  • Odpowiedz
@jcollier: Mógłbym Expression uczynić interfejsem który byłby implementowany przez Operation i Constant. Ale czy taka struktura miałaby sens? Chyba że do obecnej struktury dodać jakikolwiek interfejs jako work-around, który wykorzystałbym tylko w Parserze to definiowania typu zmiennej. Tylko jak go nazwać, żeby kod miał ręce i nogi? interface Result {}?
  • Odpowiedz
to jest źle zaprojektowane. Skoro obiekty dziedziczą po Z to m1 powinna przyjmować Z. W Twoim przypadku czemu nie operujesz po prostu na Expression?


@tell_me_more: Napisałem wyżej, że Negation, Difference itd nie udostępniają tych samych metod, więc nie wystarczyvisit(Expression e) bo stąd nie będę mógł dobrać się do metod w tych obiektach. Wszystkie klasy muszą mieć wspólny typ bazowy albo interfejs, bo parser może zwracać każdy z powyższych
  • Odpowiedz
Napisałem wyżej, że Negation, Difference itd nie udostępniają tych samych metod, więc nie wystarczyvisit(Expression e) bo stąd nie będę mógł dobrać się do metod w tych obiektach.


@Matt23: Ale visitor zna konkretną implementacje, tak jak napisał @Kresse

W każdym razie co ma robić metoda m1 ? Dlaczego nie może przyjmować jako parametru argumentu typu Z ?
  • Odpowiedz
Ale visitor zna konkretną implementacje


@Koryntiusz: Przy zastosowaniu interfejsu problemu nie ma, napisałem przecież, że zdaję sobie z tego sprawę.

W każdym razie co ma robić metoda
  • Odpowiedz
@Matt23: Technicznie nie ma roznicy czy bedzie to interfejs czy klasa abstrakcyjna. Jesli Expression nie implementuje zadnych zachowan wspolnych dla wszystkich podklas, to zrob z tego interfejs.
  • Odpowiedz
@Kresse: @Koryntiusz: @tell_me_more: K---a, rzeczywiście, to niczego nie zmienia. Już mi się pochrzaniło wszystko. Co z tego ze użyję interfejsu, skoro obiekt Negation jest przechowywany w zmiennej typu Expression? Nadal muszę rzutować aby wywołać void visit(Negation expression).

Nie wiem dlaczego, ale ubzdurało mi się, że nadanie zmiennej typu interfejsowego cokolwiek zmieni. Myślałem, że problem jest rozwiązany, a tu nadal nic. Pozostała mi albo sekwencja
  • Odpowiedz
Nadal muszę rzutować aby wywołać void visit(Negation expression).


@Matt23: Nie rozumiem czemu musisz rzutować. Obiekt zna swój typ i wywoła odpowiednią metodę wizytora.

Ma przechodzić w głąb drzewa i wypisywać pewne
  • Odpowiedz