dziedziczenie w refleksji

0

Witam mam 3 klasy posiadające różne pola
class A
class B extends A
class C extends B

tworze Gui z pól ktore sa prywatne ale tylko z danej klasy nie pobiera mi pól z klasy nadrzędnej.
Szukałem na forum nawet znalazłem Java refleksja i ustawienia wszystkich pól

ale nie potrafie tego zastosować do mojego kodu
Pola w klasie

    private Class<?> Bcc;
    private Class<?> Acc;
    private Class<?> Ccc;

przypisanie nadrzednych klas
Klasa DaneFirmy jest najniżej w dziedziczeniu

        DaneFirmy object = new DaneFirmy();    
        Ccc = object.getClass();
        Bcc = Ccc.getSuperclass();
        Acc = Bcc.getSuperclass(); 

Po zaznaczeniu JCheckBox wykonuje kod ktory dla jednej klasy pobiera pola ale dla nadrzędnej juz nie

  private  class CheckBoxHandler implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            if(isKlientFirmowy.isSelected()==true){  
              Field[] pola = dodajUzytkownikaGui.this.Ccc.getDeclaredFields();
              
              dodajUzytkownikaGui.this.panel.removeAll();
              dodajUzytkownikaGui.this.panel.setLayout(new GridLayout(pola.length+1, 2));
              for(Field f : pola){
                 dodajUzytkownikaGui.this.panel.add(new JLabel(f.getName()));
                 dodajUzytkownikaGui.this.panel.add(new JTextField());  
              }
              dodajUzytkownikaGui.this.panel.add(new JLabel("Klient firmowy"));
              dodajUzytkownikaGui.this.panel.add(isKlientFirmowy);
              dodajUzytkownikaGui.this.panel.repaint();
              pack();
            }
        }
}

gdy zmieniam Acc->Bcc->Ccc to wypisuje pola z przypisanej klasy
lub gdy zmieniam getDeclaredFields() -> getFields() to nie wypisuje wcale chyba dlatego ze są tylko prywatne pola w klasie

Field[] pola = dodajUzytkownikaGui.this.Ccc.getDeclaredFields();
Field[] pola = dodajUzytkownikaGui.this.Bcc.getDeclaredFields();
Field[] pola = dodajUzytkownikaGui.this.Acc.getDeclaredFields();

Z góry dziekuje za pomoc

0

getDeclaredFields zwraca pola zadeklarowane w definicji klasy a więc faktycznie te które instnieją w klasie
getFields zwróci Ci tylko widoczne, o ile nie tylko i wyłącznie publiczne - sprawdź w dokumentacji.
Ergo. takie zachowanie jest prawidłowe

Pamiętaj, że pola prywatne nie są dostępne w klasach dziedziczonych -> nie są elementem ich definicji -> nie będą widoczne w mechanizmach refleksji
Solution? zastosuj modyfikator protected zamiast private i wówczas będziesz widział w rozszerzeniach pola z klas bazowych, zachowując autonomie z resztą świata.

Jak koniecznie byś musiał mieć private, to jeszcze sposób na pobranie wszystkich wartości byłby taki, żeby potworzyć gettery publiczne w każdej klasie, za pomocą refleksji pobierz sobie listę getterów i je wywołuj.

0

@wedlock
po pierwsze nie obchodzimy, tylko udostępniamy wartości.
po drugie to się nazywa hermetyzacja kodu.
po trzecie gettery i settery możesz nadpisać, pól nie nadpiszesz - ubogi polimorfizm (na upartego zrobisz drugiego privata o tej samej nazwie, ale będą to nadal 2 odrębne pola)

0
Antoniossss napisał(a):

@wedlock
po pierwsze nie obchodzimy, tylko udostępniamy wartości.
po drugie to się nazywa hermetyzacja kodu.
po trzecie gettery i settery możesz nadpisać, pól nie nadpiszesz - ubogi polimorfizm (na upartego zrobisz drugiego privata o tej samej nazwie, ale będą to nadal 2 odrębne pola)

Szczerze to nie zgodzę się z tobą. Metoda jest prywatna po to żeby zachować hermetyzację klasy. Tworząc gettera i co najgorsze settera metoda staje się publiczna i dostępna poza klasą. Więc pole private mija się z celem bo metoda jest "publiczna" i dostęp do niej jest spoza klasy bazowej i inne klasy mogą korzystać.

0

Masz bardzo duzo racji, mam podobne zdanie na temat pol prywatnych i publicznych akcesorow. Ludki sie zaslaniaja polimorfizmem itp. ale w rzeczywistosci gettery / settery to jednolinijkowce ktore tylko zapisuja / zwracaja pole bezposrednio, i takie sa tez 'best practices' (sic!) ich pisania. To ze publiczne gettery otwieraja klase dla wszystkich jakos ludziom umyka.

0

no moment, jeżeli nie potrzebujesz dostępu do jakiegoś pola z zewnątrz to nie dajesz gettera tak? Jeżeli zaś udostępniasz get i set (co nie jest takie straszne) masz możliwość walidacji danych które mają być wpisane do pola. Np masz pole String nazwa, która nie może posiadać spacji (bo coś tam). Można przeprowadzić zawsze walidacje przed setterem, albo nałożyć validacje w setterze i cały projekt będzie z automatu spójny. Jeżeli pole byłoby odkryte, można by przypisać do niego każdą wartość łącznie z nulami itd. OFC jeżeli mowa o małych pisanych na kolanie programikach to pewnie nie bawmy się hermetyzację, ale popatrzcie na to od strony skalowalności.

0

gettery i settery sa jak najbardziej uzasadnione. wyobraz sobie taka sytuacje. masz settera na zmienna
int wielkosc;
i masz dwa projekty. w jednym int wielkosc jest publiczna a w drugim jest prywatna a setter jest publiczny.
w polowie projektu (po 3 miesiacach np) stwierdzasz ze tam gdzie zmieniales wielkosc zapominales o sprawdzeniu czy przypadkiem nie wprowadzamy wielkosci ujemnej!
w przypadku settera. robisz ifa w funkcji i lecisz z projektem dalej
w przypadku publicznej zmiennej musisz zmienic wszedzie tam gdzie to wykorzystywales. Czyli przejrzec wszystkie pliki i dopisac ifa. Malo tego robiac to lamiesz zasade DRY

Po takiej przygodzie doceniasz settery i gettery ;)

2

Ja nie robie nigdzie zadnego settera, uwazam ze sa zle i nic nie warte, wiec te argumenty sa o kant d**y rozbic. Gettery z zasady zdradzaja wewnetrzna budowe / implementacje klasy, wiec nie widze nigdzie tej waszej tzw. hermetyzacji. Klasy ktora uzywa czegos i udostepnia gettera nie moge juz zmienic tak, zeby tego settera nie miala lub zwracala co innego. Dodatkowo, po co zwracanie tego czegos? Zeby zrobilo cos innego? Smierdzi mi to lamaniem wielu zasad, jak np. prawa demeter.
Zwykle Value objecty (czyli np. tzw. klasy domenowe w anemicznych modelach) maja gettery i settery zazwyczaj, ktore nie robia nic tylko pisza / zwracaja do pola. Po co wiec one sa? Jesli chodzi o mozliwosc zmiany implementacji takich metod, to sory, ale co tam ma zostac zmienione? Z doswiadczenia to zmiana polega na wywaleniu jednego pola i jego gettera / settera i dodanie innego. Jak dla mnie publiczne pola sa wystarczajaco dobre. Jesli chodzi o mozliwosc walidacji itp - zacznijcie programowac w porzadnym jezyku, ktory pozwala na odnoszenie sie do pol i getterow w taki sam sposob (ew. moze bedzie trzeba przekompilowac, co i tak trzeba robic jak sie zmieni implementacje metody ;d), np. Scala czy C# (ktory ma tzw. Propertisy) jesli juz koniecznie chcecie tego uzywac. Z mojego doswiadczenia ludki tworza klasy z polami prywatnymi i definiuja ladne metody ktore cos robia, zgodnie z zasadami oo, i nagle gdzies ktos utworzy cos i doda po prostu gettera dla takiego pola - i to jest jak rak, rozprzestrzenia sie szybko i tworzy tyle zaleznosci w kodzie ze strach sie bac. Ale moze to tylko moje obserwacje, ja pracuje glownie w gownianych firmach z gownianymi programistami :(
Mowicie, ze lubicie wstawiac walidacje w setterach? Trendy raczej ida w kierunku anotowania pol / metod i pozwalaniem aby walidacje robil szeroko pojety 'kontener' (np. Bean Validation) w konkretnym momencie, ktory jest znany. Wole spojna walidacje w momencie sendu requesta ktora moge spojnie pokazac userowi niz podczas wywolywania setterow - tutaj mam tylko 1 blad pokazany, ten pierwszy, a ja wole pokazac wszystkie na raz. Jakos walidacja setterami do mnie nie przemawia.
Ogolnie nie wiem czy wiecie jaka jest historia setterow / getterow. 'Protokol' JavaBean zostal stworzony z mysla o graficznych komponentach, aby pewne konwencje umozliwily tworzenia palety komponentow i konfigurawania ich w edytorach, jak w netbeans czy gdziekolwiek. Od tego czasu wielu ludzi popelnilo wiele bledow stosujac gettery / settery wszedzie. Dodatkowo, Spring, ktory ogolnie zrobil dosc duzo dobrego dla Javy, skrzywil pokolenia programistow ktorzy wierza w settery / gettery oraz definiowanie interfejsow do wszystkiego co mozliwe.
Lubicie rowniez metody / pola statyczne, nie wiecie co to 'immutability' i pola final, prawda?

0
niezalogowany napisał(a):

w przypadku settera. robisz ifa w funkcji i lecisz z projektem dalej

void setDupa(int niezlaDupa) {
  if (niezlaDupa != 17 && jakisObiektGdzies.statycznyKodSprawdzajacyCzyZachodziWarunek(niezlaDupa)) {
    this.niezlaDupa = niezlaDupa;
  }
  // else?
}

Jak wywolam powyzej settera z 17 to jest to noop (no chyba ze kod sprawdzajacy warunek ma efekty uboczne...). Nazywasz to setterem? Chcesz miec takie cos w kodzie?
setter z ifem nie jest setterem, jest metoda biznesowa ktora ma zawarta pewna logike. Jesli tak wygladaja twoje settery, to dobrze ze nie jestem z toba w zepsole, i ciesz sie, ze nie jestem twoim przelozonym, bo bys nie przeszedl zadnego peer review.

0

W Java po prostu brakuje properties takich jak w C#.
Nie powinno używać się publicznych pól chyba ze są statyczne. W innym przypadku bardzo to źle świadczy o programiście za to dobitnie świadczy o jego wiedzy i doświadczeniu na minus.
Tutaj już nie chodzi o prosty dostęp do pól ale o utrzymanie kodu i rozwój aplikacji. Jak chcesz korzystać z polimorfizmu używając publicznych pól? Zresztą szkoda się rozpisywać bo pomysł tak pogięty, że ręce opadają :D

0

Na cholere komu polimorfizm w getterach? Pola statyczne? Swietna sprawa. Nie powinno sie uzywac bo co? Widac nie napisales nigdy prawdziwego kodu oo, gdzie gettery nie sa potrzebne, bo po co?
Co do polimorfizmu itp. to masz bardzo ograniczone podejscie (typowy Javowiec, niestety), zaloze sie ze uwazasz ze jedyny sposob na polimorfizm do dziedziczenie...

0

Zauwaz zreszta, ze ja nie pisze ze pola publiczne sa dobre; ja pisze, ze nie sa gorsze od getterow / setterow, poniewaz jestem calkowicie przeciwny takiemu dostepowi do danych, calkowicie sprzecznemu z idea oo.

0
mućka napisał(a):

Na cholere komu polimorfizm w getterach? Pola statyczne? Swietna sprawa. Nie powinno sie uzywac bo co? Widac nie napisales nigdy prawdziwego kodu oo, gdzie gettery nie sa potrzebne, bo po co?
Co do polimorfizmu itp. to masz bardzo ograniczone podejscie (typowy Javowiec, niestety), zaloze sie ze uwazasz ze jedyny sposob na polimorfizm do dziedziczenie...

W mojej opinii nie masz pojęcia o czym piszesz:-)
Jak byś przy mnie napisał klasę w Java z publicznymi polami to byś wrócił do poprawiania literówek w kodzie :-)

Z mojej strony koniec.

1

Chcesz definiowac interfejs dla setterow / getterow :O
Tak, gettery i settery sa sprzeczne z porzadnym oo. Nie ma co sie rozpisywac wiecej w tym temacie, offtop niepotrzebnie zrobilem, i do tego nie mam racji... Ale poczytajcie sobie o innych opiniach, oto cytat z pierwszego lepszego arta w necie:

"Every getter and setter in your code represents a failure to encapsulate and creates unnecessary coupling. A profusion of getters and setters (also referred to as accessors, accessor methods, and properties) is a sign of a poorly-designed set of classes."

Tutaj inny, popularny 'Python is not Java', ktory potwierdza moje wczesniejsze stwierdzenie - w Javie settery i gettery pisane sa glownie dlatego, ze ten jezyk jest tak ubogi (tak jestem glownie programista Javy - pewnie niektorzy powiedza teraz ze koderem lub nawet zwyklym wyrobnikiem, nie dbam o to - ale uwazam ten jezyk za tak prosty i w dzisiejszych czasach fatalny ze szkoda sie rozpisywac):

"In Java, you have to use getters and setters because using public fields gives you no opportunity to go back and change your mind later to using getters and setters. So in Java, you might as well get the chore out of the way up front. In Python, this is silly, because you can start with a normal attribute and change your mind at any time, without affecting any clients of the class. So, don’t write getters and setters."

W Pythonie nie ma nawet pojecia pol prywatnych (jest tylko namiastka, zwana 'name mangling', kiedy runtime pythona zmienia nazwy atrybutow zaczynajacych sie __, co nie wprowadza zadnej prywatnosci) sa tylko dobre powszechnie znane i szanowane konwencje. Jednak jesli dostep do takiego pola jest niezbedny, to jest mozliwy - w Javie tylko refleksja (mieliscie okazje kiedys rozszerzac jakis framework i dostawac kur**** jak kolejna metoda byla private lub public final? Co robicie w Javie w takim momencie? Reuse by copying?). Python nie ma private i ma sie bardzo dobrze. Clojure - tym razem jezyk funkcyjny, lisp dla jvm - tam tworcy sa zdania ze kazda klasa ktora zawiera dane do ktorych ma byc dostep z zewnatrz (czyli typowe worki na dane, value objecty, czy jak wolicie 'klasy domenowe') sa idealnie reprezentowane przez mapy (http://clojure.org/datatypes):
"Clojure has always encouraged putting such information in maps." Jesli macie gettery / settery w waszych serwisach (nawet jesli to se settery do DI) you are doing it wrong - po cholere to tam?

Jest cale mnostwo jezykow ktore daja sobie rade bez getterow / setterow. Jest cale mnostwo w ktorych nie ma pojecia prywatnosci. Sa to jezyki funkcyjne, hybrydowe, prototypowe, oo (pewnie jedyne z ktorymi macie do czynienia i z ktorych znacie tylko 1), czy jeszcze inne wiec nie mowcie ze tylko Java robi to poprawnie i to jedyna sluszna droga.
To jest w sumie problem z Java i jej jedynym slusznym frameworkiem Spring - wszyscy klepia taki sam kod bez pomyslenia. Ok, kolejna aplikacja bazodanowa ktora ma 3 formatki na krzyz (szumnie zwana 'aplikacja CRUD') moze nie wymaga wiele myslenia...

0

Typowy przyklad myslenia Javowca (tak, z tego watku, autor: @Antoniossss):
"Jak koniecznie byś musiał mieć private, to jeszcze sposób na pobranie wszystkich wartości byłby taki, żeby potworzyć gettery publiczne w każdej klasie, za pomocą refleksji pobierz sobie listę getterów i je wywołuj."
Czyli, masz pola prywatne czyli inne klasy nie maja o nich wiedziec - niewazne, jebnij im gettery, wszyscy tak robia, nie moze byc zle.

Nie wiem czy to jest dobry sposob na rozwiazanie problemu autora watku. Nie wiem czy powinien babrac sie z reflekcja, czy moze sa inne rozwiazania jego problemu, a on akurat sie uparl na refleksje bo tak; moze sa lepsze sposoby.
Wiem jednak ze dodanie publicznych getterow do pol prywatnych po to aby te gettery zczytac refleksja i wywolywac jest nic nie warte, zasyfia tylko kod niepotrzebnymi publicznymi getterami ktore od tego momentu sa dostepne dla calego swiata. Jesli juz o to chodzi to refleksja doskonale radzi sobie z odczytem pol prywatnych...

0
folly napisał(a):
mućka napisał(a):

Na cholere komu polimorfizm w getterach? Pola statyczne? Swietna sprawa. Nie powinno sie uzywac bo co? Widac nie napisales nigdy prawdziwego kodu oo, gdzie gettery nie sa potrzebne, bo po co?
Co do polimorfizmu itp. to masz bardzo ograniczone podejscie (typowy Javowiec, niestety), zaloze sie ze uwazasz ze jedyny sposob na polimorfizm do dziedziczenie...

W mojej opinii nie masz pojęcia o czym piszesz:-)
Jak byś przy mnie napisał klasę w Java z publicznymi polami to byś wrócił do poprawiania literówek w kodzie :-)

Z mojej strony koniec.

Nie mowie ze pola publiczne sa dobre czy zle; mowie, ze publiczne gettery / settery do pol prywatnych nie maja sensu... Czytaj ze zrozumieniem.

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