Как реализовать интерфейс на защищенном Java-классе - PullRequest
1 голос
/ 20 января 2011

Я пытался реализовать интерфейс для закрытого пакета Java-класса, но у меня возникли некоторые трудности в достижении этого.Ниже приведен пример.

class Foo
{
    String something(String str)
    {
        return ""str+"!";
    }
}




public interface Bar
{
    String something(String str);
}

Каков наилучший подход здесь?Моя конечная цель - реализовать интерфейс Bar в классе Foo.Я надеюсь, что смогу разыграть Foo как Bar: (Bar) Foo

Интерфейс Bar и класс Foo находятся в отдельных пакетах.Есть ли способ сделать это?

Пожалуйста, сообщите.

Ответы [ 5 ]

2 голосов
/ 20 января 2011

Вы не можете.Смысл в том, чтобы иметь доступ к нему на уровне пакета, чтобы точно не видеть этот класс снаружи.Однако, что вы можете сделать (если Foo не является окончательным) примерно так:

C:\>type *.java
//Foo.java
package foo;
class Foo {
  String something( String s ) {
    return s + "!";
  }
}  
//Bar.java
package bar;
public interface Bar {
  public String something( String s );
}    
//Baz.java
package foo;    
import bar.Bar;    
public class Baz extends Foo implements Bar {
  // make sure you're overriding
  @Override
  public String something ( String s ) {
    return super.something( s );
  }
}     
//Use it: Main.java
package bar;
import foo.Baz;   
class Main {
  public static void main( String ... args ) {
    Bar bar = new Baz();
    System.out.println( bar.something("like this?"));
  }
}

C:\>java bar.Main
like this?!

Da da!

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

Надеюсь, это поможет.

2 голосов
/ 20 января 2011

Если у вас нет контроля над классом, но вы хотите, чтобы он выглядел как API, который у вас есть, тогда вы Адаптируете для своих нужд.Подсказка: Адаптер Pattern

1 голос
/ 20 января 2011

Вам нужно будет использовать наследование или композицию, если у вас нет доступа к исходному коду Foo.

// By logically including your code in the package containing Foo,
// you can now access it. If Foo belongs to the default package, sorry.
// This also doesn't work if the package is sealed.
package where.foo.resides;

public interface Bar {
    String something(String s);
}

// Inheritance
public class FooBar extends Foo implements Bar {
    public String something(String s) {
        return super.something(s);
    }
}

// Composition
public class ComposedFooBar implements Bar {
    private final Foo delegate;
    public ComposedFooBar(Foo delegate) {
        this.delegate = delegate;
    }
    public String something(String s) {
        return delegate.something(s);
    }
}
1 голос
/ 20 января 2011

Foo необходимо реализовать Bar

protected class Foo implements Bar

Кроме того, я думаю, Foo.something должен быть публичным , чтобы реализовать Bar.something

Примечание: хотя это, вероятно, просто в качестве примера,

return ""str+"!";

должно быть:

return str + "!";

Если Foo является закрытым пакетом, и у вас нет доступа к исходному коду, только к файлам классов и / или кувшину, содержащему Foo.class, делать особо нечего - что-то, что является закрытым пакетом, невидимо для классов в пакет по умолчанию (если пакет не указан) и другие пакеты.

0 голосов
/ 20 января 2011

Вы можете попробовать использовать инжекцию байт-кода с BCEL или ASM и настроить интерфейс во время выполнения. Это сложно, хотя.

Может также быть способ изменить взаимодействие с отражением, но я сомневаюсь в этом.

Личное есть по причине.

...