Передача двух разных типов объектов одному методу в Java?

Я пытаюсь следовать этому сообщению Stackoverflow, но это не помогло моей цели чего я хотел добиться. Я хочу знать, достижимо ли это на Java. Вот постановка задачи. Я пытался изучить отражение Java, Haskel или и т. д., но в итоге у него было два разных объекта.

У меня есть два типа объектов.

  1. #P3#
  2. #P4#

Я хочу иметь метод, который принимает любой из двух объектов, указанных выше.

Например

public void runOperation(Object activeSession) {

activeSession.openLogicalChannel(APPLET_AID);
-- do the rest of operations ---
}

Я хочу использовать эту функцию, как указано ниже

if(isSetSIMSessionTrue()){
    Log.i(LOG_TAG, "Using SIM Session as its True");
    sim_session = getSim_session();
    runOperation((org.simalliance.openmobileapi.Session) sim_session);
} else{
    Log.i(LOG_TAG, "Using MSC Session as its false");
    msc_session = getMSCSession();
    runOperation((com.mobilesecuritycard.openmobileapi.Session) msc_session);
}

Я даже могу получить правильный класс объекта, используя

String classNameToBeLoaded = activeSession.getClass().getName(); 

Но все еще не удалось получить свойства объекта для объекта activeSession.

Есть ли способ передать любой из объектов сеанса методу runOperation и использовать activeSession только для выполнения остальной части операции. Поскольку оба объекта имеют одинаковые методы и функциональные возможности, но имеют доступ к другому защищенному элементу на устройстве Android. Итак, я не хочу писать два разных метода runOperation() для разных объектов. Точнее, можно ли привести тип объекта к другому объекту. Я не уверен в этом. Любые указатели или помощь будут благодарны. Надеюсь, я ясно выразился, чего хочу добиться.

PS: пожалуйста, игнорируйте синтаксис, так как я просто предоставляю некоторые фрагменты кода, чтобы прояснить мой вопрос.


person iankits    schedule 10.04.2013    source источник
comment
За что проголосовали вниз? Разве это не правильный вопрос программирования?   -  person iankits    schedule 10.04.2013


Ответы (4)


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

public void runOperation(com.mobilesecuritycard.openmobileapi.Session session) {
}

public void runOperation(org.simalliance.openmobileapi.Session session) {
}

Если цель состоит в том, чтобы уменьшить дублирование кода, используйте один метод, но пусть он принимает наименьший общий родительский класс двух типов сеансов, который, надеюсь, не Object:

public void runOperation(SessionSuperclass session) {
  // do something that can work with any type of session
  doSomethingMoreSpecific(session);
}

И при необходимости реализовать две версии doSomethingMoreSpecific(). Это был бы объектно-ориентированный способ работы, а не instanceof или отражение.

person miorel    schedule 10.04.2013
comment
Я использовал instanceOf, но думаю, вы не поняли мой вопрос. Я не хочу иметь два метода runOperation(). Это может быть самое простое и очевидное решение, которое мне не нужно. Я не хочу дублировать функцию. - person iankits; 10.04.2013
comment
Я обновил свой ответ в свете вашего комментария. Я бы не советовал вам использовать instanceof и кучу операторов if, потому что это не объектно-ориентировано. Что произойдет, если вам вдруг понадобится поддерживать третий тип сеанса? Вы добавите еще if? Это не ремонтопригодно. Поведение, зависящее от типа, должно быть выражено с помощью соответствующих языковых конструкций, таких как перегрузка методов. - person miorel; 10.04.2013
comment
Спасибо. Ага. Я думаю, что мне нужно написать две отдельные функции с учетом вашего и других ответов и на основе моих исследований в Интернете. Но в конечном итоге это приведет к тому, что два разных приложения будут упакованы в один apk для Android, чего я пытался избежать. :-| - person iankits; 10.04.2013

Вы можете сделать эту проверку в своем runOperation().

if(activeSession instanceof org.simalliance.openmobileapi.Session){
    // Type 1
}
else if(activeSession instanceof com.mobilesecuritycard.openmobileapi.Session){
    // Type 2
}
person RainMaker    schedule 10.04.2013

Одно из решений, которое приходит на ум, состоит в том, чтобы оба объекта реализовали общий интерфейс.

Например

public interface ObjectIF
{
    public void doSomething();
}

Есть несколько классов, которые реализуют интерфейс:

public class ClassOne implements ObjectIF
{
    public void doSomething() { // Code }
}

public class ClassTwo implements ObjectIF
{
    public void doSomething() { // Code }
}

Теперь с помощью вашего метода вы можете сделать что-то вроде этого:

public void doSomethingWithObject(ObjectIF object)
{
    // Provided an object implements the interface, it can be passed here.
    object.doSomething();
}
person christopher    schedule 10.04.2013

можно ли привести тип объекта к другому объекту?

Да, вы можете преобразовать.

Вы можете проверить и разыграть:

if(activeSession instanceof org.simalliance.openmobileapi.Session){
    org.simalliance.openmobileapi.Session mySession = (org.simalliance.openmobileapi.Session) activeSession 
}
else if(activeSession instanceof com.mobilesecuritycard.openmobileapi.Session) {
    com.mobilesecuritycard.openmobileapi.Session mySession = (com.mobilesecuritycard.openmobileapi.Session) activeSession 
}
person BobTheBuilder    schedule 10.04.2013
comment
благодаря. Я уже пробовал это, но объект mySession не дает mySession.openLogicalChannel (ID), как указано в объекте msc_session или sim_session. то есть msc_session.openLogicalChannel(ID). Не работает в моем контексте - person iankits; 10.04.2013
comment
Итак, приведите к объекту, у которого есть функция openLogicalChannel. - person BobTheBuilder; 10.04.2013
comment
Боюсь, это не поможет, так как в объекте mySession ничего нет. Это тоже пробовал уже. :-| - person iankits; 10.04.2013