2009-11-02 3 views
1

Я хочу знать, как идентифицировать подклассы во время выполнения в java. В моей программе я вызываю метод, который возвращает объект суперкласса. Объект может быть экземпляром любого из его подклассов. Я хочу знать, что объект является экземпляром этого подкласса во время выполнения, поэтому я могу применить его к этому подклассу и получить доступ к подклассам. Может ли кто-нибудь помочь мне в этом?определение подкласса во время выполнения

Благодаря

+0

спасибо ..Теперь я знаю, как это сделать, и я пытаюсь изменить дизайн, чтобы избежать такого типа кодирования. – daniel

ответ

4

Вызов GetClass() на объекте для доступа к объекту класса, который говорит вам фактический тип объекта. Затем вы можете сравнить это со статическим членом «.class» любого класса.

if (obj.getClass().equals(Foo.class)) { ... } 

Однако многие люди скажут, что вы предлагаете плохой дизайн. Убедитесь, что это необходимо, и рассмотрите альтернативы. Это часто необходимо для реализации таких методов, как equals().

+2

Я думаю, что instanceof - лучший подход, но вы получаете мой голос за указание, что это действительно признак того, что дизайн совершенно неправильный. – Dustin

+0

Нет смысла сравнивать объекты класса через equals(). Это можно заменить на simple ==. –

+0

Я не согласен с тем, что instanceof является решением, учитывая задание проблемы. Он заинтересован в принятии действий на основе точного класса объекта, а instanceof не совсем фиксирует это: он истинен всякий раз, когда аргумент совместим с назначением с данным классом, а не только с его экземпляром. В некоторых случаях это эквивалентно, но не все. –

0

Оператор instanceof вы можете проверить тип объекта, а затем выполнить его.

1

Использование instanceof Оператор. Вроде так

Superclass aSup = ...; 
if(aSup instanceof Subclass) { 
    Subclass aSub = (Subclass) aSup; 
    aSub.subclass_method(...); 
} 
7

Вы можете просто использовать instanceof, чтобы проверить, является ли объект экземпляром определенного класса. например:

if (animal instanceof Cat) { 
    Cat cat = (Cat) animal; 
    cat.meow(); 
} else if (animal instanceof Dog) { 
    Dog dog = (Dog) animal; 
    dog.bark(); 
} 

Однако чрезмерное InstanceOf (или вниз литья, по этому вопросу), как правило, считается признаком плохого дизайна. Вместо этого лучше использовать полиморфизм. Например, в Animal есть (возможно, абстрактный) метод «говорить», а затем каждый подкласс будет иметь другую реализацию. Приведенный выше код будет затем заменен на вызов говорить:

animal.speak(); 
+0

+1 для объяснения того, что использование 'instanceof' является симптомом плохого дизайна. – Jesper

1

Обратите внимание, InstanceOf верно, если объект типа приписы- класса, указанного. Следующие (как описано выше) будут работать

if (o instanceof Cat.class) { 
    // .. 
} else if (o instanceof Dog.class) { 
    // .. 
} else { 
    throw IllegalArgumentException("Unexpected type"); 
} 

Однако, если вы вводите новый подкласс кошки, например, Tiger, то первое предложение выше будет вызвано, если вы не обновили весь код , который сделал это.

Возможно, вы захотите найти Double Dispatch для потенциального способа , чтобы сделать это, конечно, не зная, что проблема , попытка решить эту проблему может быть неприменима.

1

Оператор «instanceof» и непосредственное сравнение объектов класса, как упоминалось выше.

Однако, если вы хотите изменить код, чтобы избежать явных проверок, я вижу два пути:

  • GoF Visitor pattern;
  • логика обработки класса конкретных Encapsulate, то есть создать что-то вроде этого:

interface Handler<T> { 
    void handle(T object); 
} 

Map<Class<?>, Handler<?>> HANDLERS = /* init handlers mappings */; 

... 

public void process(Object obj) { 
    Handler<?> handler = HANDLERS.get(obj.getClass()); 
    if (handler == null) { 
     throw new IllegalStateException("bla-bla-bla, no handler is registered for class " + obj.getClass()); 
    } 
    handler.handle(obj); 
} 
Смежные вопросы