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


247

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 ?? 안에 foo () 메소드를 구현했는지 말해 줄 수 있습니까?
Maciej Cygan

20
@MaciejCygan Java 8에서 허용
Rohit Jain

답변:


330

에 따라 이 문서 는 인터페이스의 기본 방법에 액세스 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 장 에서 찾을 수 있습니다 .


14
또한 그 경우에주의 A extends SomeOtherInterface하고 SomeOtherInterface있다 default Type method(), 당신은 단지 호출 할 수 없습니다 SomeOtherInterface.super.method()ChildClass에에서. 부모 인터페이스가 아닌 ChildClass' implements절에 열거 된 인터페이스의 기본 메소드 만 호출 할 수 있습니다 .
gvlasov

1
@ Suseika 좋은 지적, 없음과 같은 super.super.someMethod();(끔찍한 것입니다)
Richard Tingle

@gvlasov good point이지만 자식 인터페이스에서 부모 인터페이스의 기본 메소드에 액세스하는 방법은 가능합니까 ?? 업데이트 .......... 예 가능합니다.보다 자세한 설명은 stackoverflow.com/a/24280376/3791156
Raaghu

@RichardTingle 완벽한 답변!
gaurav

17

아래 코드가 작동합니다.

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

나는 이것이 위의 질문을 설명하는 가장 좋은 예라고 생각합니다. 감사합니다
Hemanth Peela

8

이 답변은 주로 닫힌 질문 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!
안녕하세요 인터페이스 푸!
안녕하세요 인터페이스 바!


3

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

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


9
OP는 다음과 같이 말합니다. "해당 메소드가 재정의 된 경우 메소드의 기본 구현을 명시 적으로 호출 할 수
있습니까?
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.