Как привести к подклассу класса объекта без использования instanceof в JAVA? - PullRequest
0 голосов
/ 16 декабря 2018

У меня проблемы с созданием приведения из расширенного класса Object к его подклассу.Следуя этому шаблону кода.

public class Athletic1 extends Object {
      public void run(){
              // run 5km
      }         
}

public class Athletic2 extends Object {

      public void run(){
            // run 10km
      }
}

class SpecificClass{
      // receive an athletic
      SpecificClass(Object obj){
            // HERE i like do something as
            // The left side dont Work
            (obj.getClass().getName) nameVariable = (obj.getClass().getName()) obj;
       }
}

class Main{
    public static void main(String[] args){
          Athletic1 a1 = new Athletic1();
          Athletic2 a2 = new Athletic2();
          SpecificClass sc1 = new SpecificClass(a1);
          SpecificClass sc2 = new SpecificClass(a2);
    }
}

Я мог бы прибегнуть к instanceOf, однако, когда у меня много подклассов Object, код становится очень обширным.Есть ли альтернатива?

        // Supose that i hava 10 Athletic Class
        // I have that do this????????
        if (obj instanceOf Athletic1)
             Athletic1 a1 = (Athletic1) obj;
        ...
        ...
        else{
             Athletic1 a10 = (Athletic10) obj;
        }

Может кто-нибудь мне помочь?Спасибо

1 Ответ

0 голосов
/ 16 декабря 2018

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

(obj.getClass().getName()) obj;

"Материал" внутри скобок должен быть идентификатором , а не выражением .Этот идентификатор должен быть именем фактического класса или фактического интерфейса, который известен во время компиляции.Это не может быть идентификатор для переменной.Он даже не может быть идентификатором параметра типа.

(obj.getClass().getName) nameVariable = ...

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


Так что можно "подклассить" экземпляр, избегая использования instanceof?

instanceof НЕ используется для создания подклассов.Тип броска делает это!instanceof фактически используется для различения подклассов.

Возможно (хотя, вероятно, не то, что вы хотите!) Различать без использования instanceof.

  1. Используйте switch в имени класса:

    switch (obj.getClass().getName()) {
    case "a.b.Athletic1":
        Athletic1 a1 = (Athletic1) obj;
        // do stuff
        break;
        ...
    case "a.b.Athletic10":
        Athletic10 a10 = (Athletic10) obj;
        // do stuff
    }
    

    Проблема: у вас все еще есть шаблонный код для различения фиксированного числа случаев.

  2. Используйте Map.

    Map<Class<?>, Consumer<?>> mapping = new Map<> {{
        put(a.b.Athletic1.class, 
            o -> {
                Athletic1 a1 = (Athletic1) o;
                // do stuff
            });
        put(a.b.Athletic10.class, 
            o -> {
                Athletic10 a10 = (Athletic10) o;
                // do stuff
            });
    }};
    
    Consumer<Object> c = mapping.get(obj.getClass());
    if (c != null) {
        c.accept(obj);
    }
    

    Преимущества:

    • Карта может заполняться динамически.
    • При необходимости Consumer объекты могут создаваться динамически как проксиклассы.(Хотя это дорого!)

    Недостаток: все еще много шаблонного.

В то время как они избегают явного instanceof, (IMO) этотак же плохо, как ваш существующий подход.«Запах кода» все еще существует.


IMO, реальным решением является использование полиморфизма Java.

  1. Создание суперкласса / интерфейса commons для Athletic classes.

  2. Создайте метод в суперклассе / интерфейсе, который представляет действие

  3. Реализуйте метод действия в каждом из Athleticклассы.

  4. Позвони ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...