в Java, как расширить реализацию взаимодействия? - PullRequest
1 голос
/ 28 мая 2011

У меня есть интерфейс, и мне кто-то обещал предоставить его реализацию.

Теперь я должен разработать класс st, чтобы я мог расширять "чью-то" реализацию.Однако я не знаю названия этой реализации.

например.

interface X{ void methodA(int); int methodB();} 

class A implements X { /*impl code here*/}

Теперь я не знаю, какой класс собирается реализовать X. Но я хочу включить этиреализации в моем коде

class B extends <Anyclass that implements interface X>
{/*other impl here*/}

Как мне это сделать?Я знаю, в дженерики вы можете указать при использовании ComparatorЯ хочу знать, есть ли что-нибудь доступное для этого случая?

Ответы [ 4 ]

2 голосов
/ 28 мая 2011

Есть ли причина, по которой вы хотите избежать композиции здесь? У вас не будет доступа к реализации загадки без имени. Вы не можете расширить ? extends X, но у вас может быть экземпляр этого. Это довольно тривиально с использованием композиции:

interface X
{
 void methodA( int param );
 int methodB();
}

class YourImpl<T extends X> implements X
{
 private T delegate;

 public YourImpl( T delegate )
 {
  this.delegate = delegate;
 }

 void methodA( int param )
 {
  delegate.methodA( param );
 }

 int methodB()
 {
  return delegate.methodB();
 }
}

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

Вообще говоря, люди тяготеют к наследованию, чтобы решить свои проблемы, даже когда состав более уместен. Я бы посоветовал пересмотреть, подходит ли вам композиция. Еще одна вещь, которую стоит рассмотреть, - может ли таинственная реализация использовать вашу реализацию, а не наоборот.

2 голосов
/ 28 мая 2011

Итак, вам нужен экземпляр X, который имеет тот же интерфейс, что и класс, который вы получаете во время выполнения, но позволяет указать, как ведут себя определенные методы X?

Если у вас есть экземпляр A во время выполнения вы можете использовать прокси-классы для создания объекта, который реализует все интерфейсы, которые реализует класс, включая X, и который переопределяет некоторые методы X, чтобы делать то, что вы хотите, ивсе остальные делегируются экземпляру.

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

Также обратите внимание, что результирующий объект не является A, он просто реализует те же интерфейсы, что и A.

2 голосов
/ 28 мая 2011

Вот ваш интерфейс:

interface X{ void methodA(int); int methodB();} 

Сделать абстрактный суперкласс:

abstract class A implements X { /*impl code here*/}

Теперь B (и любой другой класс, расширяющий A) обещает реализовать интерфейс:

class B extends A {/*other impl here*/}
1 голос
/ 28 мая 2011

Теперь я должен спроектировать класс s.t Я могу расширить «чью-то» реализацию. Однако я не знаю название этой реализации.

Это невозможно. Java не позволяет вам extend параметр общего типа. Вы можете только extend именованный класс.

Чтобы достичь того, чего вы пытаетесь достичь, вам нужно использовать какой-то тип прокси, делегирование или упаковку. Например:

public class B implements X {
    private X x;
    public B(X x) {
        this.x = x;
    }

    // delegate each method in the X interface as required; e.g.
    public int someMethod(String s) {
        return x.someMethod(s);
    }

    // add any implementations of B-specific methods.
}

Это не совсем "композиция", но я подозреваю, что это то, чего вы пытаетесь избежать. К сожалению (для вас) реальной альтернативы нет. Язык Java и JVM оба требуют, чтобы каждый класс, кроме Object, имел один определенный суперкласс.

...