Mam klasy bazowej, Statement
, który kilka innych klas dziedziczą, nazwany IfStatement
, WhereStatement
, itd ... Jaki jest najlepszy sposób, aby wykonać test w sposób if
oświadczenie w celu ustalenia, z którego klasy wywodzi się instancja klasy Statement
?Czy Java mieć „to rodzaj klasy” metody badawczej
Odpowiedz
if (obj.getClass().isInstance(Statement.class)) {
doStuffWithStatements((Statement) obj));
}
Zaletą tej techniki (w przeciwieństwie do „instanceof” słowo kluczowe) jest to, że można przejść test klasy dookoła jako przedmiot. Ale, tak, poza tym, jest to identyczne z "instanceof".
UWAGA: Celowo uniknąłem redakcji na temat tego, czy sprawdzanie instancji typu jest sprawą prawą. Tak, w większości przypadków lepiej jest użyć polimorfizmu. Ale nie o to prosił OP, a ja odpowiadam tylko na jego pytanie.
if(object instanceof WhereStatement) {
WhereStatement where = (WhereStatement) object;
doSomething(where);
}
Należy zauważyć, że ten kod zwykle oznacza, że w klasie bazowej brakuje metody polimorficznej. tj. doSomething()
powinna być metodą o abstrakcyjnej metodzie Statement
, która jest nadpisywana przez podklasy.
Dzięki za dodatkowe informacje! Przyjrzę się temu, aby sprawdzić, czy istnieje czysty sposób na ulepszenie projektu. –
+1 za odpowiedź, choć chciałbym dodać, że 'instanceof' ma wiele ważnych zastosowań - nie zawsze jest to zapach designu. Na przykład, jeśli 'doSomething()' ma zastosowanie tylko do klauzul where, wtedy ten wzorzec jest prawdopodobnie lepszy niż sztucznie tworząc 'doSomething()' część klasy Statement (gdzie nie logicznie się mieści). – mikera
Kolejny przykład użycia 'instanceof'. W JavaFX masz okienko. Muszę przejść przez drzewo węzłów potomnych. 'getChildren()' zwraca węzły. Ale jeśli jednym z węzłów jest okienko, muszę również przejść przez dzieci. Węzeł nie ma metody "getChildren()" i nie należy do niej dodawać. Tak więc muszę użyć 'node instanceof Pane', aby sprawdzić, czy muszę rzucić węzeł do okienka i przejść jego potomków. – dwilliss
Odpowiedź na pytanie to instanceof.
Należy jednak pamiętać, że jeśli twój kod wymaga instancji, jest to znak, że coś jest nie tak z twoim projektem. Są przypadki, gdy instanceof jest uzasadniony, ale są to raczej wyjątki. Zwykle, jeśli twoje podklasy muszą zachowywać się inaczej, musisz użyć polimorfizmu zamiast if().
Jedyne, co chciałbym dodać do waszego polecenia, to silna sugestia programowania przez interfejs. – monksy
To jest nie sposób na rzeczy w sposób obiektowy, to powrót do starej dychotomii kodu/danych. To niekoniecznie musi być złą rzeczą (jeśli wiesz, co robisz), ale to powinno być pozostawione w językach nieobiektywnych, takich jak C.
Przy prawidłowym projekcie nie potrzebujesz tego rodzaju zachowania . Zamiast tego konstruktu:
if (obj.getClass().isInstance(Statement.class)) {
doStuffWithStatements((Statement) obj));
}
(przeprosiny do benjismith za „kradzież” jego kod), to powinien być naprawdę czyni sam obiekt odpowiedzialny za swoje działania tak:
obj.doStuff();
wówczas każda inna obj
klasa będzie miała własną definicję dla doStuff
. To jest właściwy sposób, aby to zrobić.
Jeśli tylko podklasa może doStuff (™ paxdiabio) i masz szereg obiektów, z których niektóre są super klasy podklasy to jest to lepszy sposób to zrobić (zamiast dodawać nie op -d doStuff metody do super-klasy, które mogą być bez znaczenia (lub "po prostu źle")). – geowar
@geowar, jeśli masz kolekcję niejednorodnych rzeczy, prawdopodobnie nie powinny one * być * w kolekcji. Lub, przynajmniej, nie powinieneś powtarzać tej kolekcji w sposób, który chce zrobićStuff. Jest wiele sposobów na poradzenie sobie z tym, ale powiązanie ich z nazwą lub typem klasy może być bardzo trudne przy wprowadzaniu zmian. W świecie dziedziczenia/OO posiadanie funkcji zerowej dla nadklasy, która nie chce nic dla tej sprawy, jest właściwie całkiem dobrym rozwiązaniem, czyniąc kod przetwarzania znacznie czystszym. – paxdiablo
isAssignableFrom (java.lang.Class) z klasy to Twoja odpowiedź. http://download.oracle.com/javase/6/docs/api/java/lang/Class.html#isAssignableFrom(java.lang.Class)
Spróbuj:
if (Statement.class.isInstance(obj)) {
doStuffWithStatements((Statement) obj));
}
od Class.isInstance() Metoda ta przykład obiektu jako parametr.
- 1. Powrót rodzaj metody getClass
- 2. Czy to możliwe, aby mieć zmienną ilość typów elementów w java klasy generycznej
- 3. Extensible Haskell Rodzaj Klasy
- 4. Co to jest? rodzaj?
- 5. Błąd kompilacji Java po powrocie Rodzaj klasy ogólnej
- 6. Java Enums może mieć zachowanie?
- 7. mieć dostęp metody klasy dominującej stałe podklasy za
- 8. Czy metody klasy zwiększają wielkość instancji klasy?
- 9. Java OO: Czy to możliwe?
- 10. Czy to jest przesłonięcie metody, czy nie?
- 11. Java - parametr Zastosowanie metody klasy w parametrze
- 12. Java Enum Rodzaj standardy kodowania
- 13. Czy rodzaj wnioskowania zastosowanie w Java niezarejestrowanych leków generycznych
- 14. java wywołanie metody z innej klasy
- 15. Java: dlaczego metody statycznych interfejsów powinny mieć ciało?
- 16. Jaki jest rodzaj niemodyfikowalne listy w java
- 17. Czy w java można mieć niepodpisany ByteBuffer?
- 18. Jaki rodzaj Java jest "[B"?
- 19. Groovy Nieaktualne Metody i Eclipse - rodzaj
- 20. Metody statyczne klasy Python
- 21. Czy mogę mieć RSpec bez klasy dla metod
- 22. Czy Java "buforuje" anonimowe klasy?
- 23. Rodzaj klasy, która implementuje wiele interfejsów
- 24. Jaki rodzaj procesu tworzenia oprogramowania powinien mieć samotny programista?
- 25. Sprawdź, czy klasy Java implementują toString()
- 26. Czy ten wątek klasy Java jest bezpieczny?
- 27. Czy metody klasy Ruby są wątkowo bezpieczne?
- 28. Czy moduły mogą mieć właściwości?
- 29. Python - czy mogę programowo dekorować metody klasy z instancji klasy?
- 30. Metody LINQ to metody rozszerzeń?
Dlaczego po prostu nie użyć prostszego sprawdzania instancji? –
instanceof nie jest zły jak goto. Jest powód, dla którego został dodany do języka i dlaczego nie został przestarzały. –
+1 za nie "redagowanie informacji o tym, czy sprawdzanie instancji typu jest właściwe, czy nie" –