Java-класс, расширяющий функциональность внешнего API - PullRequest
1 голос
/ 08 января 2010

У меня есть внешний API (я не могу его изменить) с классом "A" и локальным классом "B", который переопределяет методы "A" и добавляет дополнительную функцию. Мне нужно использовать один из них в соответствии с некоторым параметром "is_A".

/ ------ API (A.java) ----- /

package A;

public class A {

    public int pingA( int value ) {

        return value;

    }

}

/ ------ мой класс (B.java) ----- /

package B;

import A.*;

public class B extends A {

    @Override
    public int pingA( int value ) {
        return value;
    }

    public int pingB( int value ) {
        return value;
    }

    public static void main(String[] args) {
        final boolean is_A = false;
        A obj;
        if (is_A) {
            obj = new A();
        } else {
            obj = new B();
        }
        if (!is_A) {
            int n = obj.pingB(3);
        }
    }
}

В этом случае я хочу использовать класс "B", но команда "int n = obj.pingB (3);" не компилируется, потому что в A. нет метода pingB Точное сообщение:

cannot find symbol
symbol: method pingB(int)
location: class A.A

Ответы [ 4 ]

7 голосов
/ 08 января 2010

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

Вы можете сделать что-то вроде:

A obj = new B();

if (obj instance of B) {
   B b = (B)obj;
   int n = b.pingB(3);
}

Здесь B - это A, но A - это не B, поэтому у него нет метода pingB (int).

2 голосов
/ 08 января 2010

Вам нужно привести obj обратно к B.

if (!is_A) {
    int n = ((B) obj).pingB(3);
}

Кстати, лучше использовать ключевое слово instanceof вместо is_A.

if (obj instanceof B) {
    int n = ((B) obj).pingB(3);
}
1 голос
/ 08 января 2010

Вам нужно привести к производному классу, чтобы иметь возможность вызывать его методы. Обычно это делается с помощью и if( obj instanceof B ), но, поскольку у вас уже есть логическое значение с этой информацией, оно будет выглядеть так:

public static void main(String[] args) { 
    final boolean is_A = false; 
    A obj; 
    if (is_A) { 
        obj = new A(); 
    } else { 
        obj = new B(); 
    } 
    if (!is_A) { 
        int n = ((B) obj).pingB(3); 
    } 
}
0 голосов
/ 08 января 2010

obj по-прежнему имеет тип A (-> вы объявили A obj;) -> таким образом привязка типа не работает для компиляции.

...