Programing

Java 8에서 기본 메소드와 추상 클래스가있는 인터페이스

lottogame 2020. 2. 14. 21:53
반응형

Java 8에서 기본 메소드와 추상 클래스가있는 인터페이스


Java 8은 Default Methods 라는 인터페이스에서 메소드의 기본 구현을 허용 하므로을 사용할 때 사이에 혼란이있는 것 같습니다 abstract class.

그렇다면 언제 기본 메소드와의 인터페이스를 사용해야하고 언제 추상 클래스를 사용해야합니까? 해당 시나리오에서 추상 클래스가 여전히 유용합니까?


기본 메소드 구현 (예 : 개인 상태)보다 클래스를 추상화하는 것이 훨씬 더 많지만, Java 8에서 선택할 때마다 default인터페이스에서 방어자 (일명. ) 메소드 를 사용해야합니다 .

기본 메소드에 대한 제한은 특정 구현 상태를 참조하지 않고 다른 인터페이스 메소드에 대한 호출 측면에서만 구현할 수 있다는 것입니다. 따라서 주요 사용 사례는보다 높은 수준의 편리한 방법입니다.

이 새로운 기능의 장점은 편리한 메소드에 추상 클래스를 사용하기 전에 구현자를 단일 상속으로 제한하기 전에 인터페이스와 최소한의 구현만으로도 실제로 깨끗한 디자인을 가질 수 있다는 것입니다 프로그래머에 대한 노력.

defaultJava 8에 메소드 를 도입하려는 원래 동기 는 기존 구현을 중단하지 않고 람다 지향 메소드로 Collections Framework 인터페이스를 확장하려는 바람이었습니다. 이것은 공공 도서관의 저자와 더 관련이 있지만 프로젝트에서도 같은 기능이 유용 할 수 있습니다. 새로운 편의를 추가 할 수있는 중앙 집중식 장소가 하나 있으며 나머지 유형 계층 구조가 어떻게 보이는지에 의존 할 필요는 없습니다.


몇 가지 기술적 차이점이 있습니다. 추상 클래스는 여전히 Java 8 인터페이스와 비교하여 더 많은 작업을 수행 할 수 있습니다.

  1. 추상 클래스는 생성자를 가질 수 있습니다.
  2. 추상 클래스는보다 구조적이고 상태를 유지할 수 있습니다.

개념적으로, 방어자 메소드의 주요 목적은 Java 8에서 새로운 기능 (람다 함수로)을 도입 한 후의 호환성입니다.


이에 대해서는이 기사 에서 설명 합니다. forEach컬렉션을 생각하십시오 .

List<?> list = …
list.forEach(…);

foreach 문은 선언되지 java.util.List않으며 java.util.Collection아직 인터페이스를 제공합니다. 확실한 해결책 중 하나는 기존 인터페이스에 새 메소드를 추가하고 JDK에서 필요한 경우 구현을 제공하는 것입니다. 그러나 일단 게시되면 기존 구현을 중단하지 않고 인터페이스에 메소드를 추가 할 수 없습니다.

기본 메소드의 이점은 이제 인터페이스에 새 기본 메소드를 추가 할 수 있으며 구현을 중단하지 않는다는 것입니다.


기사 에서 설명했듯이

Java 8의 추상 클래스와 인터페이스

기본 메소드를 도입 한 후 인터페이스와 추상 클래스가 동일한 것 같습니다. 그러나 Java 8에서는 여전히 다른 개념입니다.

추상 클래스는 생성자를 정의 할 수 있습니다. 그것들은 더 구조적이고 그들과 관련된 상태를 가질 수 있습니다. 대조적으로, 기본 메소드는 특정 구현 상태를 참조하지 않고 다른 인터페이스 메소드를 호출하는 측면에서만 구현 될 수 있습니다. 따라서 서로 다른 목적으로 사용하고 두 가지 중에서 선택하는 것은 실제로 시나리오 상황에 따라 다릅니다.


이 두 가지는 매우 다릅니다.

기본 방법은 상태를 변경하지 않고 기존 클래스에 외부 기능추가 하는 것입니다.

그리고 추상 클래스는 일반적인 상속 유형이며, 확장하려는 일반 클래스 입니다.


추상 클래스와 인터페이스를 선택할 때마다 항상 (거의) 기본 (수비수 또는 가상 확장이라고도 함) 방법을 선호해야합니다.

  1. 기본 메소드는 클래식 인터페이스 패턴과 해당 인터페이스에서 대부분 또는 모든 메소드를 구현하는 동반자 클래스를 종료했습니다. 예는 Collection and AbstractCollection입니다. 이제 기본 기능을 제공하기 위해 인터페이스 자체에서 메소드를 구현해야합니다. 인터페이스를 구현하는 클래스는 메소드를 대체하거나 기본 구현을 상속하도록 선택할 수 있습니다.
  2. 기본 방법의 또 다른 중요한 용도는 interface evolution입니다. 내가 다음과 같이 공을 가지고 있다고 가정 해보십시오.

    public class Ball implements Collection { ... }

이제 Java 8에서는 새로운 기능이 도입되었습니다. stream인터페이스에 추가 된 메소드 를 사용하여 스트림을 얻을 수 있습니다 . stream기본 방법이 아닌 경우 Collection인터페이스에 대한 모든 구현은이 새로운 방법을 구현하지 않기 때문에 실패했을 것입니다. 기본이 아닌 메소드를 인터페이스에 추가하는 것은 아닙니다 source-compatible.

그러나 클래스를 다시 컴파일하지 않고이 클래스를 포함하는 오래된 jar 파일을 사용한다고 가정 해보십시오 Ball. 이 누락 된 메소드없이 클래스가 정상적으로로드되고 인스턴스를 만들 수 있으며 모든 것이 올바르게 작동하는 것 같습니다. 그러나 프로그램이 stream인스턴스를 호출하면 메소드를 Ball얻습니다 AbstractMethodError. 따라서 방법을 기본값으로 설정하면 두 가지 문제가 해결되었습니다.


의 검색어에 대해

그렇다면 언제 기본 메소드와의 인터페이스를 사용해야하고 언제 추상 클래스를 사용해야합니까? 해당 시나리오에서 추상 클래스가 여전히 유용합니까?

자바 문서 는 완벽한 답변을 제공합니다.

인터페이스와 비교 한 추상 클래스 :

추상 클래스는 인터페이스와 유사합니다. 인스턴스화 할 수 없으며 구현 여부에 관계없이 선언 된 다양한 메소드를 포함 할 수 있습니다.

그러나 추상 클래스를 사용하면 정적 및 최종이 아닌 필드를 선언하고 공개, 보호 및 개인 콘크리트 메소드를 정의 할 수 있습니다.

인터페이스를 사용하면 모든 필드가 자동으로 공개, 정적 및 최종이며, 선언하거나 정의한 모든 메소드 (기본 메소드)는 공개입니다. 또한 추상적이든 아니든 하나의 클래스 만 확장 할 수 있지만 여러 인터페이스를 구현할 수 있습니다.

이들 각각의 사용 사례는 아래 SE 게시물에 설명되어 있습니다.

인터페이스와 추상 클래스의 차이점은 무엇입니까?

해당 시나리오에서 추상 클래스가 여전히 유용합니까?

예. 그들은 여전히 ​​유용합니다. 그들은 비 정적이 아닌 마지막 방법을 포함 할 수 있습니다 및 특성 ( 보호, 공공뿐만 아니라 민간 에도 자바-8 인터페이스)로 이용 가능합니다.


Java 인터페이스의 기본 메소드는 인터페이스 진화를 가능하게 합니다.

기존 인터페이스가 제공되는 경우, 이전 버전의 인터페이스와의 이진 호환성을 유지하면서 메소드를 추가하려면 기본 또는 정적 메소드를 추가하십시오. 실제로, 인터페이스에 추가 된 추상 메소드는이 인터페이스를 구현하는 클래스 또는 인터페이스에 의해 구현되어야합니다.

정적 메소드는 클래스에 고유합니다. 기본 메소드는 클래스 인스턴스에 고유합니다.

기존 인터페이스에 기본 메소드를 추가하면이 인터페이스를 구현하는 클래스 및 인터페이스가이를 구현할 필요가 없습니다. 그들은 할 수있다

  • 기본 메소드를 구현하고 구현 된 인터페이스의 구현을 대체합니다.
  • 추상적으로 만드는 메소드 (구현없이)를 다시 선언하십시오.
  • 아무것도하지 마십시오 (그런 다음 구현 된 인터페이스의 기본 메소드는 단순히 상속됩니다).

여기 에 주제에 대한 자세한 내용이 있습니다 .


Remi Forax 규칙은 추상 클래스로 디자인하지 않는다는 것입니다. 인터페이스를 사용하여 앱을 디자인합니다 . Watever는 언어에 관계없이 Java 버전입니다. 그것은 지원을받습니다 I의 nterface의 분리 원칙SOL I D의 원칙.

나중에 추상 클래스를 사용하여 코드를 분해 할 수 있습니다. 이제 Java 8을 사용하면 인터페이스에서 직접 수행 할 수 있습니다. 이것은 더 이상 시설이 아닙니다.


언제 기본 메소드와의 인터페이스를 사용해야하고 언제 추상 클래스를 사용해야합니까?

이전 버전과의 호환성 : 인터페이스가 수백 개의 클래스로 구현되고 인터페이스를 수정하면 인터페이스를 구현하는 다른 많은 클래스에 필수적이지 않더라도 모든 사용자가 새로 추가 된 메소드를 강제로 실행한다고 상상해보십시오 .기능적 인터페이스

사실 및 제한 사항 :

1- 클래스 또는 추상 클래스가 아닌 인터페이스 내에서만 선언 될 수 있습니다.

2- 몸을 제공해야 함

3- 인터페이스에서 사용되는 다른 일반적인 방법과 같이 추상적이라고 가정하지 않습니다.


Java 8에서 인터페이스는 다음과 같은 차이점이 있지만 추상 클래스처럼 보입니다.

1) 추상 클래스는 클래스이므로 Java 인터페이스의 다른 제한 사항으로 제한되지 않습니다. 예를 들어 abstract 클래스 state를 가질 수 있지만 Java 인터페이스의 상태는 가질 수 없습니다.

2) 기본 메소드가있는 인터페이스와 추상 클래스의 의미 론적 차이점은 추상 클래스 안에 생성자를 정의 할 수 있지만 Java에서 인터페이스 내부에 생성자를 정의 할 수 없다는 것입니다


Java 인터페이스의 기본 메소드는 함수의 더미 구현을 제공하기 위해 더 많이 사용되므로 모든 추상 메소드를 하나만 처리하려는 경우에도 모든 추상 메소드를 선언하는 고통에서 해당 인터페이스의 구현 클래스를 절약 할 수 있습니다. 따라서 인터페이스의 기본 메소드는 어댑터 클래스 개념을 대체합니다.

그러나 추상 클래스의 메소드는 모든 하위 클래스가 공통 기능을 대체하는 데 필요한 경우에만 대체해야하는 의미있는 구현을 제공해야합니다.


다른 답변에서 언급했듯이 Collections 프레임 워크에서 이전 버전과의 호환성을 제공하기 위해 인터페이스에 구현을 추가하는 기능이 추가되었습니다. 역 호환성을 제공하는 것이 인터페이스에 구현을 추가하는 유일한 이유라고 주장합니다.

그렇지 않으면 인터페이스에 구현을 추가하면 인터페이스가 처음에 추가 된 이유에 대한 기본 법칙을 위반하는 것입니다. Java는 다중 상속을 허용하는 C ++과 달리 단일 상속 언어입니다. 인터페이스는 다중 상속에 따른 문제를 유발하지 않고 다중 상속을 지원하는 언어와 함께 제공되는 타이핑 이점을 제공합니다.

보다 구체적으로, Java는 구현의 단일 상속 만 허용하지만 인터페이스의 다중 상속은 허용합니다. 예를 들어, 다음은 유효한 Java 코드입니다.

class MyObject extends String implements Runnable, Comparable { ... }

MyObject 하나의 구현 만 상속하지만 세 개의 계약을 상속합니다.

Java는 다중 상속 상속을 전달했습니다. 여러 상속 상속에는이 답변의 범위를 벗어난 수많은 문제가 있기 때문입니다. 다중 구현 상속 문제없이 계약의 다중 상속 (인터페이스)을 허용하는 인터페이스가 추가되었습니다.

내 요점을 뒷받침하기 위해 책 The Java Programming Language, 4th edition의 Ken Arnold와 James Gosling의 인용문이 있습니다 .

단일 상속은 유용하고 올바른 디자인을 배제합니다. 다중 상속의 문제는 구현의 다중 상속에서 발생하지만 많은 경우 다중 상속은 여러 추상 계약과 하나의 구체적인 구현을 상속하는 데 사용됩니다. 구현을 상속하지 않고 추상 계약을 상속 할 수있는 수단을 제공하면 다중 구현 상속 문제없이 다중 상속의 타이핑 이점을 얻을 수 있습니다. 추상 계약의 상속을 인터페이스 상속 이라고 합니다. Java 프로그래밍 언어는 interface유형 을 선언 할 수 있도록하여 인터페이스 상속을 지원 합니다.


개방 / 폐쇄 원칙을 먼저 생각하십시오. 인터페이스의 기본 메소드는이를 위반합니다. 이것은 Java의 나쁜 기능입니다. 나쁜 디자인, 나쁜 아키텍처, 낮은 소프트웨어 품질을 권장합니다. 기본 방법을 완전히 사용하지 않는 것이 좋습니다.

몇 가지 질문을 해보십시오. 왜 메소드를 추상 클래스에 넣을 수 없습니까? 그런 다음 둘 이상의 추상 클래스가 필요합니까? 그런 다음 반원이 무엇을 책임 지는지 생각해보십시오. 단일 클래스에 넣을 모든 메소드가 실제로 동일한 목적을 달성한다고 확신합니까? 여러 목적을 구별 한 다음 각 목적에 따라 클래스를 여러 클래스로 분할 할 수 있습니다.

참고 : https://stackoverflow.com/questions/19998454/interface-with-default-methods-vs-abstract-class-in-java-8



반응형