Слияние интерфейсов без слияния - PullRequest
16 голосов
/ 25 октября 2011

Я думал, есть ли в C ++ или Java способ сделать что-то подобное

Interface IF1{
    ....
};

Interface IF2{
    ....
};


function f(Object o : Implements IF1, IF2){
    ...
}

означает систему типов, которая позволяет требовать реализации интерфейсов.

Ответы [ 6 ]

28 голосов
/ 25 октября 2011

Вы можете сделать это на Java:

public <I extends IF1 & IF2> void methodName(I i){

....

}

Таким образом вы заставляете I реализовать два ваших интерфейса, иначе он даже не скомпилируется.

11 голосов
/ 25 октября 2011

В C ++ мы можем использовать std::is_base_of<IF1, Derived>.Это должно использоваться с фактическим производным и базовым типом и будет простым в использовании с помощью tempalte s.

template<typename T>
void f (T obj)
{
  static_assert(is_base_of<IF1,T>::value && is_base_of<IF2,T>::value,
  "Error: Not implementing proper interfaces.");
  ...
}

Если T (производное class) не реализуетIF1 и IF2, тогда утверждение не будет выполнено во время компиляции.

3 голосов
/ 25 октября 2011

в C ++ вы можете сделать что-то подобное:

template <typename T>
void f(T &o)
{
    IF1 &i1 = o;
    IF2 &i2 = o;

    //function body
}

строки с указателем интерфейса необходимы для того, чтобы T реализовывал оба интерфейса (это вызовет ошибку компилятора, если это не так).

2 голосов
/ 25 октября 2011

Используя библиотеки повышения ( type_traits , enable_if , и_ ), вы можете сделать что-то довольно сложное.

template <typename T>
typename boost::enable_if<           // Check whether
    boost::mpl::and_<                // Both of the following conditions are met
        boost::is_base_of<IF1, T>,   // T derives from IF1
        boost::is_base_of<IF2, T>    // T derives from IF2
        >
    >
>::type
function(T& t)
{
  // ...
}

в моем коде есть некоторые причуды, но вы поняли.

1 голос
/ 25 октября 2011

Что не так с:

interface IF1IF2 extends IF1, IF2 {}

void f(IF1IF2 o) {
}

Зачем слишком усложнять вещи?

1 голос
/ 25 октября 2011

В Java нет ничего подобного, я бы добавил третий элемент, реализующий два интерфейса, и использовал бы его в качестве параметра. И для меня это имеет смысл, поскольку третий объект не является ни IF1, ни IF2, это просто IF3.

interface a {
  int foo();
}


interface b {
  long foo2();
}

interface c extends a, b {
  long daaa();
}

public class TestInterface {

  void someMethod (c theThird) {
    return;
  }
}

это имеет смысл для меня.

EDIT: Не знал о

public <I extends a & b> void methodName(I i){

}

Однако я нашел это запутанным. Если объект должен реализовывать два разных интерфейса, я предпочитаю иметь третий. ИМХО это чище.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...