programing

Java에서 기본 메서드를 명시적으로 호출하는 중

prostudy 2022. 6. 11. 11:45
반응형

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();

이것은 다음과 같이 사용할 수 있습니다(인터페이스가 있는 경우).A그리고.C둘 다 기본 메서드가 있습니다.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 인터페이스는 여러 상속의 몇 가지 측면을 도입합니다.기본 메서드에는 구현된 함수 본문이 있습니다.슈퍼 클래스에서 메서드를 호출하려면 키워드를 사용합니다.super단, 슈퍼인터페이스를 사용하는 경우에는 명시적으로 이름을 붙여야 합니다.

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

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

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

public class Example extends ParentClass implements InterfaceFoo, InterfaceBar {
    public void hello() {
        super.hello(); // (note: ParentClass.super could not be used)
        InterfaceFoo.super.hello();
        InterfaceBar.super.hello();
    }
    
    public static void main(String[] args) {
        new Example().hello();
    }
}

출력:

안녕하세요 Parent Class!
Hello Interface Foo!
Hello Interface Bar!

인터페이스의 디폴트 방식을 덮어쓸 필요는 없습니다.그냥 이렇게 불러주세요.

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

인터페이스의 디폴트 방식을 덮어쓸지 여부는 선택에 따라 달라집니다.디폴트는 구현 클래스 객체에 직접 호출할 수 있는 클래스의 인스턴스 메서드와 비슷하기 때문입니다.(짧은 디폴트에서는 인터페이스의 메서드는 클래스를 구현함으로써 상속됩니다).

다음 예를 생각해 보겠습니다.

interface I{
    default void print(){
    System.out.println("Interface");
    }
}

abstract class Abs{
    public void print(){
        System.out.println("Abstract");
    }

}

public class Test extends Abs implements I{

    public static void main(String[] args) throws ExecutionException, InterruptedException 
    {

        Test t = new Test();
        t.print();// calls Abstract's print method and How to call interface's defaut method?
     }
}

언급URL : https://stackoverflow.com/questions/19976487/explicitly-calling-a-default-method-in-java

반응형