Использование экземпляра vs для добавления isSomething() в базовый класс

Скажем, у меня есть эта иерархия классов:

Animal <-- FourLegged <-- Dog
Animal <-- FourLegged <-- ....

Animal <-- ThreeLegged <-- ... (what has 3 legs?)

Animal <-- TwoLegged <-- Chicken
Animal <-- TwoLegged <-- ...

(Забудьте, что такое научные термины для четырехногих и двуногих животных, но что касается точки, верно? :))

Если у меня есть объект Animal, и мне нужно знать, является ли это FourLegged или если это TwoLegged, я бы обычно делал animalObject instanceof FourLegged.

Это медленнее, чем добавление в класс Animal группы isFourLegged(), isThreeLegged(), isTwoLegged()?

(Я хотел бы знать, как это влияет на производительность. Это НЕ проектное упражнение. Поэтому я был бы признателен, если вы не будете тратить время на предложение переписать класс)

Редактирование Некоторые люди предложили добавить "getNumberOfLegs()", что вполне обоснованно дано в этом конкретном примере. Но предположим, что точка НЕ имеет число ног, но чтобы получить, какой тип животного это.

3 ответа

Если ваши подклассы не добавляют никакого поведения и это всего лишь способ указать количество ножек, вы должны пойти с этим рефакторингом под названием Replace Subclass With Fields. => нет необходимости в подклассах.

В противном случае добавьте полиморфный метод, например: numberOfLegs(), реализуемый каждым из ваших подклассов Animal.


Вопрос сосредотачивается вокруг "скорости" исполнения: один путь медленнее другого?

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

Сказав это, просто увидеть, что у instanceof потенциально больше работы:

  1. Установите checkclass= this.getClass()
  2. Является ли checkclass== целевым классом? Если да, верните true.
  3. Есть ли у checkClass суперкласс? Если нет, верните false.
  4. Установите checkclass= суперкласс класса checkClass
  5. Перейти к 2

(С потенциально большим усилием, связанным с возможностью интерфейсов, в этом случае я предполагаю, что реализация JVM знает, что целевой класс не является интерфейсом и может использовать эти знания в свою пользу.)

Однако вызов виртуального метода не требует никакой потенциальной итерации: вытащите указатель функции из объекта vtable и вызовите его.

Но когда целевой класс является непосредственным суперклассом объекта, тогда существует только одна итерация при перемещении иерархии классов. В этом случае "быстрее" или "медленнее", чем вызов виртуального метода?

Итог: это зависит. Когда производительность важна, измерьте. В отсутствие данных, явно указывающих на узкое место производительности с кодом, предпочитайте код, который является ясным, кратким, понятным и поддерживаемым.


Пытаться

Animal animal = new Dog();

 if(animal.getClass().isAssignableFrom(FourLegged.class)){
 System.out.println("FourLegged");
 }

Сделайте это таким же образом для других

licensed under cc by-sa 3.0 with attribution.