Abstact 클래스와 인터페이스의 차이점
- Java 8의 추상 클래스와 인터페이스
- 개념적 차이 :
Java 8의 인터페이스 기본 메소드
- 기본 방법은 무엇입니까?
- 기본 메소드를 사용하여 ForEach 메소드 컴파일 오류가 해결되었습니다.
- 기본 방법 및 다중 상속 모호성 문제
- Java 인터페이스 기본 메소드에 대한 중요한 사항 :
자바 인터페이스 정적 메소드
- Java 인터페이스 정적 메소드, 코드 예제, 정적 메소드 및 기본 메소드
- Java 인터페이스 정적 메소드에 대한 중요한 사항 :
자바 기능 인터페이스
Java 8의 추상 클래스와 인터페이스
Java 8 인터페이스 변경에는 인터페이스의 정적 메소드 및 기본 메소드가 포함됩니다. Java 8 이전에는 인터페이스에 메소드 선언 만있을 수있었습니다. 그러나 Java 8부터 인터페이스에 기본 메소드와 정적 메소드를 가질 수 있습니다.
기본 메소드를 도입 한 후 인터페이스와 추상 클래스가 동일한 것 같습니다. 그러나 Java 8에서는 여전히 다른 개념입니다.
추상 클래스는 생성자를 정의 할 수 있습니다. 그것들은 더 구조적이고 그들과 관련된 상태를 가질 수 있습니다. 대조적으로, 기본 메소드는 특정 구현 상태를 참조하지 않고 다른 인터페이스 메소드를 호출하는 측면에서만 구현 될 수 있습니다. 따라서 서로 다른 목적으로 사용하고 두 가지 중에서 선택하는 것은 시나리오 상황에 따라 다릅니다.
개념적 차이 :
추상 클래스는 인터페이스의 골격 (즉, 부분) 구현에 유효하지만 일치하는 인터페이스가 없으면 존재하지 않아야합니다.
따라서 추상 클래스가 효과적으로 보이지 않는 인터페이스의 골격 구현으로 축소되면 기본 메소드도 이것을 제거 할 수 있습니까? 결정적으로 : 아니요! 인터페이스를 구현하려면 거의 항상 기본 메소드에없는 클래스 작성 도구의 일부 또는 전부가 필요합니다. 그리고 어떤 인터페이스가 그렇지 않으면 분명히 특별한 경우이며, 당신을 타락으로 이끌지 않아야합니다.
Java 8의 인터페이스 기본 메소드
Java 8에는“ 기본 메소드 ”또는 (수 비기 메소드) 새로운 기능이 도입되어 개발자가 이러한 인터페이스의 기존 구현을 중단하지 않고도 인터페이스에 새로운 메소드를 추가 할 수 있습니다. 구체적인 클래스가 해당 메소드에 대한 구현을 제공하지 못하는 상황에서 기본값으로 사용할 인터페이스 정의 구현을 허용하는 유연성을 제공합니다.
작동 방식을 이해하기 위해 작은 예를 고려하십시오.
public interface OldInterface {
public void existingMethod();
default public void newDefaultMethod() {
System.out.println("New default method"
+ " is added in interface");
}
}
다음 클래스는 Java JDK 8에서 성공적으로 컴파일됩니다.
public class OldInterfaceImpl implements OldInterface {
public void existingMethod() {
// existing implementation is here…
}
}
OldInterfaceImpl 인스턴스를 작성하는 경우 :
OldInterfaceImpl obj = new OldInterfaceImpl ();
// print “New default method add in interface”
obj.newDefaultMethod();
기본 메소드는 최종적이지 않으며 동기화 할 수 없으며 오브젝트의 메소드를 대체 할 수 없습니다. 그것들은 항상 공개적이며 짧고 재사용 가능한 방법을 작성하는 능력을 심각하게 제한합니다.
기본 메소드는 구현을 포함하므로 클래스 구현에 영향을 미치지 않고 인터페이스에 제공 할 수 있습니다. 구현으로 정의 된 인터페이스의 각 추가 된 메소드는 구현 클래스에 영향을 미치지 않습니다. 구현 클래스는 인터페이스에서 제공하는 기본 구현을 대체 할 수 있습니다.
기본 방법을 사용하면 이러한 인터페이스의 이전 구현을 중단하지 않고 기존 인터페이스에 새로운 기능을 추가 할 수 있습니다.
기본 메소드가 포함 된 인터페이스를 확장하면 다음을 수행 할 수 있습니다.
- 기본 방법을 재정의하지 않고 기본 방법을 상속합니다.
- 서브 클래스에서 재정의하는 다른 방법과 유사한 기본 방법을 재정의합니다.
- 기본 메소드를 abstract로 다시 선언하여 서브 클래스가이를 대체하도록합니다.
기본 메소드를 사용하여 ForEach 메소드 컴파일 오류가 해결되었습니다.
Java 8의 경우 JDK 콜렉션이 확장되었으며 forEach 메소드가 전체 콜렉션에 추가되었습니다 (람다와 함께 작동 함). 일반적인 방법으로 코드는 다음과 같습니다.
public interface Iterable<T> {
public void forEach(Consumer<? super T> consumer);
}
따라서 결과적으로 컴파일 오류가있는 각 구현 클래스가 있으므로 기존 구현을 변경하지 않도록 필수 구현으로 기본 메소드를 추가했습니다.
기본 메소드를 사용한 반복 인터페이스는 다음과 같습니다.
public interface Iterable<T> {
public default void forEach(Consumer
<? super T> consumer) {
for (T t : this) {
consumer.accept(t);
}
}
}
구현 클래스를 손상시키지 않고 JDK 인터페이스 에 스트림 을 추가하는 데 동일한 메커니즘이 사용되었습니다 .
기본 방법 및 다중 상속 모호성 문제
java 클래스는 여러 인터페이스를 구현할 수 있고 각 인터페이스는 동일한 메소드 서명으로 기본 메소드를 정의 할 수 있으므로 상속 된 메소드가 서로 충돌 할 수 있습니다.
아래 예를 고려하십시오.
public interface InterfaceA {
default void defaultMethod(){
System.out.println("Interface A default method");
}
}
public interface InterfaceB {
default void defaultMethod(){
System.out.println("Interface B default method");
}
}
public class Impl implements InterfaceA, InterfaceB {
}
위의 코드는 다음 오류로 컴파일되지 않습니다.
java : Impl 클래스는 InterfaceA 및 InterfaceB 유형에서 defaultMethod ()에 대해 관련되지 않은 기본값을 상속합니다.
이 클래스를 수정하려면 기본 메소드 구현을 제공해야합니다.
public class Impl implements InterfaceA, InterfaceB {
public void defaultMethod(){
}
}
또한 자체 구현이 아닌 수퍼 인터페이스에서 제공하는 기본 구현을 호출하려는 경우 다음과 같이 수행 할 수 있습니다.
public class Impl implements InterfaceA, InterfaceB {
public void defaultMethod(){
// existing code here..
InterfaceA.super.defaultMethod();
}
}
우리는 새로운 방법의 일부로 기본 구현 또는 둘 다를 선택할 수 있습니다.
Java 인터페이스 기본 메소드에 대한 중요한 사항 :
- Java 인터페이스 기본 메소드는 구현 클래스를 중단 할 염려없이 인터페이스를 확장하는 데 도움이됩니다.
- Java 인터페이스 기본 메소드는 인터페이스와 추상 클래스의 차이점을 보완합니다.
- Java 8 인터페이스 기본 메소드는 모든 Collections 클래스 메소드가 인터페이스 자체에서 제공 될 수있는 것과 같은 유틸리티 클래스를 피하는 데 도움이됩니다.
- Java 인터페이스 기본 메소드는 기본 구현 클래스를 제거하는 데 도움이되고 기본 구현을 제공 할 수 있으며 구현 클래스는 대체 할 클래스를 선택할 수 있습니다.
- 인터페이스에 기본 메소드를 도입 한 주요 이유 중 하나는 람다 표현식을 지원하도록 Java 8에서 Collections API를 향상시키는 것입니다.
- 계층 구조의 클래스에 서명이 동일한 메소드가있는 경우 기본 메소드는 관련이 없습니다. 기본 메소드는 java.lang.Object의 메소드를 대체 할 수 없습니다. 추론은 매우 간단합니다. Object는 모든 Java 클래스의 기본 클래스이기 때문입니다. 따라서 인터페이스에 기본 메소드로 정의 된 Object 클래스 메소드가 있더라도 Object 클래스 메소드가 항상 사용되므로 쓸모가 없습니다. 그렇기 때문에 혼동을 피하기 위해 Object 클래스 메서드를 재정의하는 기본 메서드를 가질 수 없습니다.
- Java 인터페이스 기본 메소드는 Defender 메소드 또는 가상 확장 메소드라고도합니다.
리소스 링크 :
- Java 8의 기본 메소드와 추상 클래스가있는 인터페이스
- JDK 8 시대의 추상 클래스와 인터페이스
- 가상 확장 방법을 통한 인터페이스 진화
자바 인터페이스 정적 메소드
Java 인터페이스 정적 메소드, 코드 예제, 정적 메소드 및 기본 메소드
Java 인터페이스 정적 메소드는 구현 클래스에서이를 대체 할 수 없다는 점을 제외하고 기본 메소드와 유사합니다. 이 기능은 구현 클래스에서 구현이 잘못되었을 때 원하지 않는 결과를 피하는 데 도움이됩니다. 간단한 예를 통해이를 살펴 보겠습니다.
public interface MyData {
default void print(String str) {
if (!isNull(str))
System.out.println("MyData Print::" + str);
}
static boolean isNull(String str) {
System.out.println("Interface Null Check");
return str == null ? true : "".equals(str) ? true : false;
}
}
이제 구현이 좋지 않은 isNull () 메소드가있는 구현 클래스를 보자.
public class MyDataImpl implements MyData {
public boolean isNull(String str) {
System.out.println("Impl Null Check");
return str == null ? true : false;
}
public static void main(String args[]){
MyDataImpl obj = new MyDataImpl();
obj.print("");
obj.isNull("abc");
}
}
isNull (String str)은 간단한 클래스 메서드이며 인터페이스 메서드를 재정의하지 않습니다. 예를 들어, @Nride () 메소드에 @Override 어노테이션을 추가하면 컴파일러 오류가 발생합니다.
이제 우리는 응용 프로그램을 실행할 때 다음과 같은 결과를 얻습니다.
인터페이스 널 점검
Impl 널 점검
인터페이스 메소드를 정적에서 기본값으로 만들면 다음과 같은 출력이 나타납니다.
Impl 널 점검
MyData 인쇄 ::
Impl 널 점검
Java 인터페이스 정적 메소드는 인터페이스 메소드에만 표시됩니다. MyDataImpl 클래스에서 isNull () 메소드를 제거하면 MyDataImpl 오브젝트에이 메소드를 사용할 수 없습니다. 그러나 다른 정적 메소드와 마찬가지로 클래스 이름을 사용하여 인터페이스 정적 메소드를 사용할 수 있습니다. 예를 들어 유효한 진술은 다음과 같습니다.
boolean result = MyData.isNull("abc");
Java 인터페이스 정적 메소드에 대한 중요한 사항 :
- Java 인터페이스 정적 메소드는 인터페이스의 일부이므로 구현 클래스 객체에 사용할 수 없습니다.
- Java 인터페이스 정적 메소드는 유틸리티 메소드 (예 : 널 검사, 콜렉션 정렬 등)를 제공하는 데 유용합니다.
- Java 인터페이스 정적 메소드는 구현 클래스가이를 대체하지 못하도록하여 보안을 제공하는 데 도움이됩니다.
- Object 클래스 메소드에 대한 인터페이스 정적 메소드를 정의 할 수 없습니다.“이 정적 메소드는 Object에서 인스턴스 메소드를 숨길 수 없습니다”라는 컴파일러 오류가 발생합니다. Object는 모든 클래스의 기본 클래스이므로 동일한 서명을 가진 하나의 클래스 레벨 정적 메소드와 다른 인스턴스 메소드를 가질 수 없으므로 java에서는 허용되지 않기 때문입니다.
- java 인터페이스 정적 메소드를 사용하여 Collections와 같은 유틸리티 클래스를 제거하고 모든 정적 메소드를 해당 인터페이스로 이동하여 쉽게 찾고 사용할 수 있습니다.
자바 기능 인터페이스
게시물을 마치기 전에 Functional 인터페이스에 대해 간략하게 소개하고 싶습니다. 정확히 하나의 추상 메소드가있는 인터페이스를 기능 인터페이스라고합니다.
@FunctionalInterface
인터페이스를 기능 인터페이스로 표시하기 위해 새로운 주석 이 도입되었습니다. @FunctionalInterface
주석은 기능 인터페이스에 추상적 인 메소드가 실수로 추가되는 것을 방지하는 기능입니다. 선택이지만 사용하는 것이 좋습니다.
함수형 인터페이스는 오랫동안 기다려 왔으며, 람다 식을 사용하여 인스턴스화 할 수 있기 때문에 Java 8의 기능을 많이 찾고 있습니다. 람다 식 및 메소드 참조에 대한 대상 유형을 제공하기 위해 기능 인터페이스가 많은 새 패키지 java.util.function이 추가되었습니다. 향후 포스트에서 기능적 인터페이스와 람다 식을 살펴볼 것입니다.
자원 위치 :
- Java 8 인터페이스 변경 – 정적 메소드, 기본 메소드