2009-05-29 12 views

Odpowiedz

53
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.

+3

Dlaczego po prostu nie użyć prostszego sprawdzania instancji? –

+5

instanceof nie jest zły jak goto. Jest powód, dla którego został dodany do języka i dlaczego nie został przestarzały. –

+10

+1 za nie "redagowanie informacji o tym, czy sprawdzanie instancji typu jest właściwe, czy nie" –

64
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.

+0

Dzięki za dodatkowe informacje! Przyjrzę się temu, aby sprawdzić, czy istnieje czysty sposób na ulepszenie projektu. –

+5

+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

+0

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

6

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().

+0

Jedyne, co chciałbym dodać do waszego polecenia, to silna sugestia programowania przez interfejs. – monksy

0

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ć.

+0

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

+0

@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

1

Spróbuj:

if (Statement.class.isInstance(obj)) { 
    doStuffWithStatements((Statement) obj)); 
} 

od Class.isInstance() Metoda ta przykład obiektu jako parametr.

Powiązane problemy