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
'programing' 카테고리의 다른 글
VueJs의 동적 컴포넌트에 동적 소품을 결합하는 방법 2 (0) | 2022.06.11 |
---|---|
C/C++에서 \x는 무엇을 의미합니까? (0) | 2022.06.11 |
Vue-CLI 구성 요소 오류: 템플릿 컴파일러를 사용할 수 없는 Vue 런타임 전용 빌드를 사용하고 있습니다. (0) | 2022.06.11 |
Android로 파일을 다운로드하고 진행 상황을 ProgressDialog로 표시 (0) | 2022.06.11 |
C++ 코드를 C로 변환하는 방법 (0) | 2022.06.11 |