[java] Java에서 기본 메소드를 명시 적으로 호출

Java 8에는 기존 구현을 수정하지 않고도 인터페이스를 확장 할 수있는 기본 방법 이 도입되었습니다 .

다른 인터페이스에서 충돌하는 기본 구현으로 인해 해당 메서드가 재정의되었거나 사용할 수없는 경우 메서드의 기본 구현을 명시 적으로 호출 할 수 있는지 궁금합니다.

interface A {
    default void foo() {
        System.out.println("A.foo");
    }
}

class B implements A {
    @Override
    public void foo() {
        System.out.println("B.foo");
    }
    public void afoo() {
        // how to invoke A.foo() here?
    }
}

위의 코드를 고려하면 A.foo()클래스 B의 메소드에서 어떻게 호출 합니까?



답변

에 따라 이 문서 는 인터페이스의 기본 방법에 액세스 A사용

A.super.foo();

이것은 다음과 같이 사용될 수 있습니다 (인터페이스 AC기본 방법이 있다고 가정 foo())

public class ChildClass implements A, C {
    @Override
    public void foo() {
       //you could completely override the default implementations
       doSomethingElse();
       //or manage conflicts between the same method foo() in both A and C
       A.super.foo();
    }
    public void bah() {
       A.super.foo(); //original foo() from A accessed
       C.super.foo(); //original foo() from C accessed
    }
}

A그리고 C둘 다 가질 수 .foo()방법 및 특정 기본 구현을 선택할 수 있습니다 또는 당신은 당신의 새의 일환으로 (또는 둘 다) 하나를 사용할 수 있습니다 foo()방법. 동일한 구문을 사용하여 구현 클래스의 다른 메소드에서 기본 버전에 액세스 할 수도 있습니다.

메소드 호출 구문에 대한 공식적인 설명은 JLS의 15 장 에서 찾을 수 있습니다 .


답변

아래 코드가 작동합니다.

public class B implements A {
    @Override
    public void foo() {
        System.out.println("B.foo");
    }

    void aFoo() {
        A.super.foo();
    }

    public static void main(String[] args) {
        B b = new B();
        b.foo();
        b.aFoo();
    }
}

interface A {
    default void foo() {
        System.out.println("A.foo");
    }
}

산출:

B.foo
A.foo


답변

이 답변은 주로 닫힌 질문 45047550 에서 오는 사용자를 위해 작성 되었습니다.

Java 8 인터페이스는 다중 상속의 일부 측면을 소개합니다. 기본 메소드에는 구현 된 함수 본문이 있습니다. 수퍼 클래스에서 메소드를 호출하려면 keyword를 사용할 수 super있지만 수퍼 인터페이스로이를 작성하려면 명시 적으로 이름을 지정해야합니다.

class ParentClass {
    public void hello() {
        System.out.println("Hello ParentClass!");
    }
}

interface InterfaceFoo {
    default public void hello() {
        System.out.println("Hello InterfaceFoo!");
    }
}

interface InterfaceBar {
    default public void hello() {
        System.out.println("Hello InterfaceBar!");
    }
}

public class Example extends ParentClass implements InterfaceFoo, InterfaceBar {
    public void hello() {
        super.hello(); // (note: ParentClass.super is wrong!)
        InterfaceFoo.super.hello();
        InterfaceBar.super.hello();
    }

    public static void main(String[] args) {
        new Example().hello();
    }
}

산출:

안녕하세요 ParentClass!
안녕하세요 인터페이스 푸!
안녕하세요 인터페이스 바!


답변

인터페이스의 기본 방법을 재정의 할 필요가 없습니다. 다음과 같이 부르십시오.

public class B implements A {

    @Override
    public void foo() {
        System.out.println("B.foo");
    }

    public void afoo() {
        A.super.foo();
    }

    public static void main(String[] args) {
       B b=new B();
       b.afoo();
    }
}

산출:

A.foo


답변