2016-04-02 4 views
1

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

У меня есть класс Entity и несколько подклассов, Building и Creature являются актуальными здесь.

У меня есть метод setTarget(Entity e), который я бы хотел использовать для классов Building и Creature, потому что на этом уровне они идентичны.

Мне интересно, можно ли отлировать e в Building или Creature в зависимости от того, какой тип это, а не создавать 2 целых метода с одним и тем же кодом.

private void setTarget(Entity e) { 
    if (e.getType.equals("Creature")) { 
     Creature c = (Creature)e; //rest of code assumes c is now a creature rather than a building 
    } 
} 

Я понимаю, что я мог бы сделать это, поставив целевую механику в Entity классе, но тогда код будет иметь никакого значения для всех других подклассов, которые не имеют/нуждаются цели.

Любая помощь или советы будут очень благодарны, спасибо заранее.

EDIT: Я смотрел в instanceof, и он определенно очищает код немного, но никто не понимал, что я имел в виду;

private void setTarget(Entity e) { 
    if (e instanceof Creature) { 
     Creature c = (Creature)e; 
    } else if (e instanceof Building) { 
     Building c = (Building)e; 
    } 
    //Building OR Creature code here ie; 
    c.setTarget(); 
} 

Возможно ли это?

+0

Похоже, вы хотите Factory Pattern. Если вы используете полиморфизм, это может быть легко достигнуто. –

+1

Почему вы поместили весь этот код в одну строку? Это невозможно прочитать. –

+0

Вы можете использовать 'e.getClass(). Equals (Creature.class)' или 'e instanceof Creature' в вашей инструкции' if'. – Majora320

ответ

1

Вы можете использовать ключевое слово Java instanceof или getClass(). Разница между этими двумя в том, что если, скажем, класс SmallBuilding подклассов Building, то mySmallBuilding instanceof Building возвращает истину, в то время как mySmallBuilding.getClass().equals(Building.class) вернет ложь, потому что вызов getClass() на SmallBuilding будет возвращать различные Class объекта, чем класс Building «s. Сказав это, обычно рекомендуется использовать instanceof в зависимых от подкласса программах, таких как ваши, и getClass(), например, при написании метода equals() (поскольку оба объекта должны быть одного класса). Вот пример того, как это будет работать:

private void setTarget(Entity e) { 
    if (e instanceof Creature) { 
     Creature c = (Creature)e; 
     // Creature-specific code here 
    } else if (e instanceof Building) { 
     Building b = (Building)e; 
     // Building-specific code here 
    } 
    // Could add an else for other Entity subclasses (might throw UnsupportedOperationException) 
} 

Edit: На основе редактирования вы сделали на ваш вопрос, вы могли бы сделать что-то вроде этого:

private void setTarget(Entity e) { 
    if (e instanceof Creature) { 
     Creature c = (Creature)e; 
     c.setTarget(); 
    } else if (e instanceof Building) { 
     Building b = (Building)e; 
     b.setTarget(); 
    } 
    // Could add an else for other Entity subclasses (might throw UnsupportedOperationException) 
} 

Вы сделать должны иметь setTarget() в операциях if. Другим вариантом было бы определить интерфейс для setTarget(), например, так:

public interface Targetable { 
    public void setTarget(); 
} 

А затем Building и Creature impliment Targetable. Затем можно определить setTarget() как:

private void setTarget(Targetable t) { 
    t.setTarget(); 
} 

Или:

private void setTarget(Entity e) { 
    if (t instanceof Targetable) { 
     ((Targetable)t).setTarget(); 
    } 
} 
+0

Окей экземпляр, безусловно, лучший способ сделать это, чем то, как я сейчас использую, спасибо. – Flash

+0

@Flash Сделано редактирование, которое, я думаю, очень поможет вам с вашей проблемой. – Majora320

+0

Я никогда раньше не использовал интерфейс, но похоже, что я хочу делать, я посмотрю, как они работают! Спасибо! Извините, что я еще не знал этого материала. – Flash

2

Зачем вам нужно различать Creature и Building?

я бы, вероятно, создать интерфейс Targetable (или что-то с лучшим названием), который содержит метод setTarget() и реализуется Creature и Building.

Таким образом, в методе setTarget(Entity e) вам не нужно запрашивать Creature и Building (и, возможно, даже более классов в будущем), но вы проверяете только для e instanceof Targetable, брось к этому типу интерфейса и запустить setTarget() на него.

Примечание: Необходимость использования instanceof и литья часто является признаком того, что ваш код не структурировано оптимальным образом ...

+0

Поскольку я редактировал «Targetable» в своем ответе, вы отправили это сообщение ... – Majora320

+0

@ Majora320: Ха-ха, похоже, «Targetable» - хорошая идея, если мы оба пришли к нему самостоятельно; -) Я все равно оставлю свой ответ, может быть, это помогает кому-то лучше понять из-за разных формулировок. Даже если это не помогает, это не повредит: -P – siegi

+0

И вы, и @ Majora320 думаете, что реализовать интерфейс - это путь, поэтому я смотрю на это. Я слежу за учебниками по youtube, которые, к сожалению, никогда не заканчиваются, и пытались продолжить работу без них. Так что да, мой код, вероятно, не структурирован слишком оптимистично, но я не знаю, что я могу с этим поделать. – Flash

Смежные вопросы