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();
}
}
匿名の内部クラスを作成して呼び出す必要なしに、implementsBからデフォルトの機能インターフェースの動作を呼び出す方法はありますか?
これには副作用があり(implementsAのメソッドを2回呼び出す)、必要なのは親の実装への呼び出しであり、その後、必要に応じて、子の実装が子のデフォルトの実装を呼び出して特殊化できるようにします。ご覧のとおり、親の実装を呼び出すのは非常に簡単ですが、子インターフェースを実装するクラスに間接層を追加しない限り、デフォルトの実装の書き換えを回避する方法はありません。 。
たとえば、リソースへのロック解除または提供されたアクセスがデータベースであり、Bが2番目のリソース(別のデータベース)のロックを解除した場合、コードがAをロック解除し、次にBが機能インターフェイスを使用してこのコントラクトを強制する方法がないため、 AとBが呼び出されます。1レベルの深さでそれを行うことができますが、Nレベルの深さは不可能のように見えます。
ラムダを使用して、高価な呼び出しを行わずに、ライブラリのユーザーに操作のセマンティックな順序を強制するつもりでした。
この質問は、「Javaのデフォルトメソッドを明示的に呼び出す」とまったく同じではありません。この質問は、親インターフェースのデフォルトメソッドを呼び出すだけでなく、Nレベルの深さのインターフェースに関するものだからです。
interface default
を使用して、継承されたメソッドを呼び出すことができInterfaceName.super
ます。ルールは他のsuper
メソッド呼び出しの場合と同じです。オーバーライドした継承メソッドを呼び出すことはできますが、継承メソッドがオーバーライドした可能性のあるメソッドを直接呼び出すことはできません。例えば
interface A
{
void foo();
default void toOverride() {
System.out.println("A");
}
}
interface B extends A
{
default void toOverride() {
A.super.toOverride();
System.out.println("B");
}
}
interface C extends B
{
default void toOverride() {
A.super.toOverride();// does not work
B.super.toOverride();
System.out.println("B");
}
}
class D implements B
{
public void toOverride() {
}
public void foo() {
D.this.toOverride();
B.super.toOverride();
A.super.toOverride(); // does not work!
}
}
ただし、オーバーライドする各メソッドがそのスーパーメソッドを呼び出す場合は、一連の呼び出しがあります。ただし、ここではインターフェイスについて説明していることに注意してください。実装はsuper
、まったく呼び出すことなく、常にデフォルトのメソッドをオーバーライドできます。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加