같은 방식의 클래스 내 2개의 인터페이스를 실장한다.어떤 인터페이스 방식이 재정의됩니까?
메서드 이름과 시그니처가 같은2개의 인터페이스그러나 단일 클래스에서 구현되는 경우 컴파일러는 어떤 메서드가 어떤 인터페이스인지 어떻게 식별합니까?
예:
interface A{
int f();
}
interface B{
int f();
}
class Test implements A, B{
public static void main(String... args) throws Exception{
}
@Override
public int f() { // from which interface A or B
return 0;
}
}
를 실장하고 있으며, 각 타입이 2개의 인터페이스를 실장하고 있는 ,interface
동일한 시그니처를 가진 메서드를 정의합니다.실제로 메서드는 1개뿐이며 구분할 수 없습니다.예를 들어 두 메서드의 반환 유형이 충돌하는 경우 컴파일 오류가 발생합니다.의 「」, 「」, 「」, 「」의 에 발생할 가능성이 .interface
도 .interface
슈퍼 ★★★★★★★★★★★★★★★★★.class
또는 제네릭의 활자 삭제로 인한 충돌일 수도 있습니다.
호환성 예시
를 들어, 이 에서는 '예', '예', '예', '예', '예', '예', '예', '예', '예', '예', '예', '예', '예'가 있습니다.interface Gift
에는)가 .present()
선물하기) 및 예: 선물하기)도 있습니다.interface Guest
에는)도 .present()
method(예:게스트는 존재하지만 존재하지 않습니다).
Presentable johnny
망원경은 둘 다이다Gift
그리고 싱크는Guest
.
public class InterfaceTest {
interface Gift { void present(); }
interface Guest { void present(); }
interface Presentable extends Gift, Guest { }
public static void main(String[] args) {
Presentable johnny = new Presentable() {
@Override public void present() {
System.out.println("Heeeereee's Johnny!!!");
}
};
johnny.present(); // "Heeeereee's Johnny!!!"
((Gift) johnny).present(); // "Heeeereee's Johnny!!!"
((Guest) johnny).present(); // "Heeeereee's Johnny!!!"
Gift johnnyAsGift = (Gift) johnny;
johnnyAsGift.present(); // "Heeeereee's Johnny!!!"
Guest johnnyAsGuest = (Guest) johnny;
johnnyAsGuest.present(); // "Heeeereee's Johnny!!!"
}
}
위의 스니펫은 컴파일하여 실행합니다.
1개뿐이라는 점에 주의해 주십시오. @Override
필요!!!그 이유는Gift.present()
그리고 그리고.Guest.present()
있""@Override
- 등가" (JLS 8.4.2).
따라서, 따라서,johnny
의 실장은 1개뿐입니다present()
그리고 이것은 여러분이 치료하는지 그리고 당신이 어떻게 대하는지는 중요하지 않다 중요하지 않다.johnny
, 등은 으로서도Gift
혹은 또는 로서Guest
오직 하나 메서드를 호출하는 것이다.호출하는 메서드는 1개뿐입니다.
비호환성 예시
다음 예에서는 상속된 두 가지 방법이 다른 방법을 보여 줍니다.@Override
- - 일치:
public class InterfaceTest {
interface Gift { void present(); }
interface Guest { boolean present(); }
interface Presentable extends Gift, Guest { } // DOES NOT COMPILE!!!
// "types InterfaceTest.Guest and InterfaceTest.Gift are incompatible;
// both define present(), but with unrelated return types"
}
는 또한 를 ""에서하는 것"이라는 것을 한 번복합니다.interface
회원 선언의 일반적인 규칙을 준수해야 한다., 여기 있습니다.Gift
★★★★★★★★★★★★★★★★★」Guest
present()
되지 않는 반환 1 " " " " " " " " : 1 " 1void
boolean
같은 이유로, 당신이 할 수 없는 것은void present()
a. a. a.boolean present()
이 예에서는 컴파일 오류가 발생합니다.
요약
하다, 하다, 하다, 하다, 하다, 하다, 하는 방법들을 수 .@Override
-불일치, 메서드 덮어쓰기 및 숨김의 통상적인 요건에 따릅니다.그들이 있기 때문에 @Override
- 일관성이 있습니다.실행할 수 있는 방법은 1개뿐이기 때문에 구별하거나 선택할 필요가 없습니다.
.이 어떤 하면 됩니다.왜냐하면 컴파일러가 어떤 인터페이스용인지 결정되면@Override
같은 수법입니다.
잠재적인 비호환성을 해결하는 것은 까다로운 작업일 수 있지만, 이는 전혀 다른 문제입니다.
레퍼런스
- JLS 8.4.2 메서드시그니처
- JLS 8.4.8 상속, 덮어쓰기 및 숨기기
- 덮어쓰기 및 숨기기 JLS 8.4.8.3 요건
- JLS 8.4.8.4 오버라이드 등가 시그니처를 사용한 상속 방식
- "클래스가 재정의 등가 서명을 가진 여러 메서드를 상속할 수 있습니다."
이것은 이 질문의 중복으로 표시되어 있습니다.https://stackoverflow.com/questions/24401064/understanding-and-solving-the-diamond-problems-in-java
다중 상속 문제가 발생하려면 Java 8이 필요하지만 여전히 diamon 문제가 아닙니다.
interface A {
default void hi() { System.out.println("A"); }
}
interface B {
default void hi() { System.out.println("B"); }
}
class AB implements A, B { // won't compile
}
new AB().hi(); // won't compile.
JB Nizet의 코멘트로, 이것을 수정해 주세요.
class AB implements A, B {
public void hi() { A.super.hi(); }
}
단, 고객님은 고객님이 고객님께 문의할 수 있는
interface D extends A { }
interface E extends A { }
interface F extends A {
default void hi() { System.out.println("F"); }
}
class DE implement D, E { }
new DE().hi(); // prints A
class DEF implement D, E, F { }
new DEF().hi(); // prints F as it is closer in the heirarchy than A.
컴파일러에 관한 한 이 두 가지 방법은 동일합니다.둘 다 하나의 구현이 있을 것이다.
이 두 가지 방법이 실질적으로 동일하다면 동일한 구현을 가져야 한다는 점에서 문제가 되지 않습니다.(각 인터페이스의 매뉴얼에 따라) 계약상 다를 경우 문제가 발생합니다.
식별할 수 있는 것은 아무것도 없습니다.인터페이스는 메서드 이름과 시그니처만 금지합니다.양쪽 인터페이스의 이름과 시그니처가 완전히 같은 메서드를 사용하는 경우 구현 클래스는 하나의 구체적인 메서드로 두 인터페이스 메서드를 구현할 수 있습니다.
단, 2개의 인터페이스 메서드의 시멘틱컨트랙트가 모순되는 경우는 거의 손실입니다.그때, 1개의 클래스로 양쪽의 인터페이스를 실장할 수 없습니다.
인터페이스와 마찬가지로 메서드를 선언하고 있습니다.이러한 양쪽 인터페이스를 실장하는 구체적인 클래스는 메서드는 1개뿐입니다(양쪽 모두 반환 타입에 같은 이름을 가지고 있습니다).문제가 없을 겁니다.당신은 구체적인 수업에서 그 방법을 정의할 수 있을 것입니다.
단, 2개의 인터페이스에 이름이 같지만 반환 타입이 다른 메서드가 있으며 구체적인 클래스에서2개의 메서드를 실장하고 있는 경우:
아래 코드를 참조해 주세요.
public interface InterfaceA {
public void print();
}
public interface InterfaceB {
public int print();
}
public class ClassAB implements InterfaceA, InterfaceB {
public void print()
{
System.out.println("Inside InterfaceA");
}
public int print()
{
System.out.println("Inside InterfaceB");
return 5;
}
}
컴파일러는 메서드 "public void print()"를 취득하면 먼저 인터페이스A를 검색하여 취득합니다.그러나 반환 유형이 인터페이스 B의 메서드와 호환되지 않는다는 컴파일 시간 오류가 발생합니다.
컴파일러에 문제가 생겼군요.
이 방법으로는 이름이 같지만 반환 유형이 다른2개의 인터페이스를 구현할 수 없습니다.
둘 다 같다면 상관없습니다.인터페이스 방식당 하나의 구체적인 방법으로 둘 다 구현합니다.
인터페이스를 어나니머스로서 실장해 주세요.
public class MyClass extends MySuperClass implements MyInterface{
MyInterface myInterface = new MyInterface(){
/* Overrided method from interface */
@override
public void method1(){
}
};
/* Overrided method from superclass*/
@override
public void method1(){
}
}
두 가지 방법을 모두 구현하고 모호성을 피하기 위해 다음 두 가지 접근방식을 사용할 수도 있습니다.
접근법 1:
App.java
-
public class App {
public static void main(String[] args) {
TestInterface1 testInterface1 = new TestInterface1();
TestInterface2 testInterface2 = new TestInterface2();
testInterface1.draw();
testInterface2.draw();
}
}
TestInterface1.java
-
public class TestInterface1 implements Circle {
}
TestInterface2.java
-
public class TestInterface2 implements Rectangle {
}
Circle.java
-
public interface Circle extends Drawable {
@Override
default void draw() {
System.out.println("Drawing circle");
}
}
Rectangle.java
-
public interface Rectangle extends Drawable {
@Override
default void draw() {
System.out.println("Drawing rectangle");
}
}
Drawable.java
-
public interface Drawable {
default void draw() {
System.out.println("Drawing");
}
}
출력 -
Drawing circle
Drawing rectangle
어프로치 2:
App.java
-
public class App {
public static void main(String[] args) {
Circle circle = new Circle() {
};
Rectangle rectangle = new Rectangle() {
};
circle.draw();
rectangle.draw();
}
}
Circle.java
-
public interface Circle extends Drawable {
@Override
default void draw() {
System.out.println("Drawing circle");
}
}
Rectangle.java
-
public interface Rectangle extends Drawable {
@Override
default void draw() {
System.out.println("Drawing rectangle");
}
}
Drawable.java
-
public interface Drawable {
default void draw() {
System.out.println("Drawing");
}
}
출력 -
Drawing circle
Drawing rectangle
언급URL : https://stackoverflow.com/questions/2801878/implementing-two-interfaces-in-a-class-with-same-method-which-interface-method
'source' 카테고리의 다른 글
Panda read_csv: low_memory 및 dtype (0) | 2022.09.23 |
---|---|
phpunit에서 단일 테스트 방법을 실행하는 방법은 무엇입니까? (0) | 2022.09.23 |
ScopeKey가 nuxt.js 인증 모듈에서 작동하지 않음 (0) | 2022.09.23 |
개체를 문자열로 변환 (0) | 2022.09.22 |
시간 범위 내에서 5분 간격으로 그룹화 (0) | 2022.09.22 |