реализация неявного неявного интерфейса Java - PullRequest
1 голос
/ 23 декабря 2010

Недавно наткнулся на интересную функцию, которая, однако, может привести к неожиданному выводу в Eclipse функции «добавления нереализованных методов». Какое «googl-способное» название концепции языка стоит за этой «неявной неявной реализацией»?

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

interface CallmeIfc {
  public void callme();
}

class CallmeCode {
  public void callme() {
    // implementation  
  }
}

class CallmeImpl extends CallmeCode implements CallmeIfc {
  // empty class body
}

public static void main(String[] args) {
  CallmeIfc me = (CallmeIfc) new CallmeImpl();
  me.callme(); // calls CallmeCode.callme()
}

Ответы [ 3 ]

2 голосов
/ 23 декабря 2010

В CallmeImpl открытый метод callme () наследуется от CallmeCode, поэтому CallmeImpl уважает контракт, определенный в CallmeIfc.

Затем в вашем методе main () полиморфизм позволяет вам назначить экземпляр подкласса.(CallmeImpl) на ссылку на суперкласс или суперинтерфейс - в данном конкретном случае ссылку "me" типа CallmeIfc (здесь вы опечатка, BTW).

1 голос
/ 25 декабря 2010

На самом деле это похоже на ошибку компилятора: спецификация языка Java пишет :

Метод экземпляра m1, объявленный в класс C переопределяет другой экземпляр метод, m2, объявленный в классе A, если все следующее верно:

  • C является подклассом A.
  • Подпись m1 является подписью (§8.4.2) подписи m2.
  • Либо
    • m2 является общедоступным, защищенным или объявленным с доступом по умолчанию в том же пакете, что и C или
    • m1 переопределяет метод m3, m3 отличный от m1, m3 отличный от m2, так что m3 переопределяет m2.

В вашем случае первое условие не выполняется: метод callme объявлен в классе CallMeCode, который не является подтипом CallmeIfc.

Редактировать : Боба прав, Спецификация различает реализацию и переопределение. На самом деле, это на самом деле мандаты наблюдаемое поведение:

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

Спецификация не объясняет, почему.

1 голос
/ 23 декабря 2010

Хотя класс CallmeCode не реализует интерфейс CallmeIfc, он обеспечивает необходимую реализацию. Это как если бы класс CallmeCode реализует интерфейс. Это работало бы также с этим кодом:

interface CallmeIfc {
    public void callme();
}

class CallmeCode implements CallmeIfc {
    public void callme() {
      // implementation  
    }
}

class CallmeImpl extends CallmeCode implements CallmeIfc {
   // empty class body
}

В вашем случае это нормально, потому что класс CallmeCode имеет метод callme. Если бы метод был назван иначе, он не скомпилировался бы.

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