В java 8 у меня есть что-то вроде этого:
package test;
public class SimpleFuncInterfaceTest {
public static void carryOutWork(AFunctionalInterface sfi){
sfi.doWork();
}
public static void main(String[] args) {
carryOutWork(() -> System.out.println("Do work in lambda exp impl..."));
AImplementor implementsA = new AImplementor();
//carryOutWork(() -> implementsA.doWork());
BImplementor implementsB = new BImplementor();
carryOutWork(() -> implementsB.doWork());
}
}
@FunctionalInterface
interface AFunctionalInterface {
public void doWork();
default public void doSomeWork(){
System.out.println("FOO");
}
}
@FunctionalInterface
interface BFunctionalInterface extends AFunctionalInterface {
@Override
default public void doSomeWork(){
System.out.println("BAR");//Unreachable in same object?
}
}
class AImplementor implements AFunctionalInterface {
@Override
public void doWork() {
doSomeWork();
}
}
class BImplementor extends AImplementor implements BFunctionalInterface {
public void doSomeWork(){
super.doSomeWork();
new BFunctionalInterface(){
@Override
public void doWork() {
}}.doSomeWork();
System.out.println("WUK WUK");
}
@Override
public void doWork() {
doSomeWork();
}
}
Есть ли способ вызвать поведение функционального интерфейса по умолчанию из реализации B без необходимости создавать анонимный внутренний класс и вызывать его?
Это имеет побочный эффект (вызов метода inventorysA 2 раза), что желательно, так это вызов родительской реализации, а затем дочерняя реализация может вызывать дочернюю реализацию по умолчанию вместе с некоторой специализацией, если это необходимо. Как вы можете видеть, вызвать реализацию родителя очень просто, но я не вижу способа избежать переписывания реализации по умолчанию, если я не добавлю уровень косвенности в класс, реализующий дочерний интерфейс, и нет способа обеспечить это .
Например, если A разблокировал или предоставил доступ к ресурсу, скажем, к базе данных, а B разблокировал второй ресурс (другую базу данных), я не вижу способа заставить код разблокировать A, а затем B обеспечить выполнение этого контракта с помощью функциональных интерфейсов, требуя, чтобы А и Б называться. На один уровень в глубину вы можете это сделать, но на N уровней похоже, что это невозможно.
Я намеревался использовать лямбда-выражения, чтобы избежать дорогостоящих вызовов, но чтобы обеспечить семантический порядок операций для пользователей моей библиотеки.
Этот вопрос не совсем не похож на «Явный вызов метода по умолчанию в Java», поскольку этот вопрос касается интерфейсов на уровне N, а не просто вызова метода родительских интерфейсов по умолчанию.
BFunctionalInterface.doSomeWork
изBImplementor
? - person Boris the Spider   schedule 18.06.2014