Явский полиморфизм - PullRequest
       10

Явский полиморфизм

1 голос
/ 10 января 2010

Рассмотрим следующий код:

public abstract class Base {
       public void getAnswer();
}

public class Derived1 extends Base {
       public void getAnswer() {
       }
}

public class Derived2 extends Base {
       public void getAnswer() {
       }
}


public class Main {

   public final int DERIVED1 = 1;
   public final int DERIVED2 = 2;

   public Base b;

   public static void Main() {

      int which_obj = which();

      switch (which_obj) {
      case DERIVED1: Derived1 derived1 = new Derived1();
                     // construct object
                     b = derived1;
                     break;
      case DERIVED2: Derived1 derived1 = new Derived1();
                     // construct object
                     b = derived2;
                     break;
      }

      b.getAnswer();
   }
}

здесь мы используем регистр переключателя, чтобы решить, какой объект построить, и, соответственно, мы создаем его и присваиваем его b для использования полиморфизма.

какое преимущество дает нам полиморфизм?

Теперь есть метод, с помощью которого мы можем избежать случая переключения. скажем: есть преобразование из int в String, которое возвращает «Derived1» или «Derived2». дана строка, содержащая название класса. Теперь я могу создать объект, заданный строкой, содержащей имя класса. что-то вроде:

Base b = construct_obj(str);

вызов библиотеки construct_obj автоматически находит класс obj из байт-кодов и возвращает ссылку на объект. тогда я могу избежать случая переключения. как правило, у меня будет 100 классов производных.

Ответы [ 2 ]

5 голосов
/ 10 января 2010

Ну, вы можете создать Map<Integer, Class<? extends Base>>, а затем использовать Class.newInstance для создания экземпляра с отражением. Это не будет работать так же хорошо, и есть различные ошибки, которые не будут видны до времени выполнения, но это будет работать.

Вот пример кода.

import java.util.*;

abstract class Base {}
class Derived1 extends Base {}
class Derived2 extends Base {}

public class Test
{
    public static void main(String[] args)
    {
        Map<Integer, Class<? extends Base>> map = 
            new HashMap<Integer, Class<? extends Base>>();

        map.put(1, Derived1.class);
        map.put(2, Derived2.class);

        int which = 2; // For example

        Class<? extends Base> clazz = map.get(which);
        if (clazz == null)
        {
            // Invalid choice. Do whatever.
        }
        else
        {
            try
            {
                Base base = clazz.newInstance();
                // Use base
            }
            catch (InstantiationException e)
            {
                // Handle exception or whatever
            }
            catch (IllegalAccessException e)
            {
                // Handle exception or whatever
            }            
        }
    }
}

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

Другая альтернатива - иметь фабричные экземпляры, а не использовать конструкторы - это было бы «безопаснее» (с точки зрения отсутствия ошибок при переносе), но, вероятно, значительно больше кода. (В C # было бы легко использовать лямбда-выражения; Java 7 также может сделать это предпочтительным решением.)

1 голос
/ 10 января 2010

Вы можете позвонить Class.newInstance

Class cl = Class.forName("com.stackoverflow.Derived1");
Base b = cl.newInstance();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...