Java 8에서는 Default Methods 라는 인터페이스에서 메소드의 기본 구현을 허용합니다 .
나는 (with ) interface default method
대신 언제 그런 종류의을 사용할 것인지 혼동 합니다.abstract class
abstract method(s)
그렇다면 언제 기본 메소드와의 인터페이스를 사용해야하고 추상 클래스 (추상 메소드와 함께)를 사용해야합니까? 해당 시나리오에서 추상 클래스가 여전히 유용합니까?
Java 8에서는 Default Methods 라는 인터페이스에서 메소드의 기본 구현을 허용합니다 .
나는 (with ) interface default method
대신 언제 그런 종류의을 사용할 것인지 혼동 합니다.abstract class
abstract method(s)
그렇다면 언제 기본 메소드와의 인터페이스를 사용해야하고 추상 클래스 (추상 메소드와 함께)를 사용해야합니까? 해당 시나리오에서 추상 클래스가 여전히 유용합니까?
답변:
기본 메소드 구현 (예 : 개인 상태)보다 클래스를 추상화하는 것이 훨씬 더 많지만 Java 8에서 선택할 때마다 default
인터페이스에서 방어자 (일명. ) 메소드 를 사용해야합니다 .
기본 메소드에 대한 제한은 특정 구현 상태를 참조하지 않고 다른 인터페이스 메소드에 대한 호출 측면에서만 구현할 수 있다는 것입니다. 따라서 주요 사용 사례는보다 높은 수준의 편리한 방법입니다.
이 새로운 기능의 장점은 편리한 메소드에 대해 추상 클래스를 사용하기 전에 구현자를 단일 상속으로 제한하기 전에 인터페이스와 최소한의 구현만으로 실제로 깨끗한 디자인을 가질 수 있다는 것입니다. 프로그래머에 대한 노력.
default
Java 8에 메소드 를 도입하려는 원래 동기 는 기존 구현을 중단하지 않고 람다 지향 메소드로 Collections Framework 인터페이스를 확장하려는 바람이었습니다. 이것은 공공 도서관의 저자와 더 관련이 있지만 동일한 기능이 프로젝트에서도 유용하다는 것을 알 수 있습니다. 새로운 편의성을 추가 할 수있는 중앙 집중식 장소가 하나 있으며 나머지 유형 계층 구조가 어떻게 보이는지에 의존 할 필요는 없습니다.
몇 가지 기술적 차이점이 있습니다. 추상 클래스는 여전히 Java 8 인터페이스와 비교하여 더 많은 작업을 수행 할 수 있습니다.
개념적으로 방어자 메소드의 주요 목적은 Java 8에서 새로운 기능 (람다 함수로)을 도입 한 후의 호환성입니다.
public static final
인터페이스 의 필드를 "상태"로 설명하지 않습니다 . 이 static
부분은 특정 인스턴스와 전혀 관련이 없음을 의미합니다. 이것은 클래스 인스턴스화에 할당 되며 , 인스턴스 생성 후 와 다릅니다 .
이에 대해서는이 기사 에서 설명 합니다. forEach
컬렉션 에 대해 생각하십시오 .
List<?> list = …
list.forEach(…);
foreach 문은 선언되지
java.util.List
않으며java.util.Collection
아직 인터페이스를 제공합니다. 확실한 해결책 중 하나는 기존 인터페이스에 새 메소드를 추가하고 JDK에서 필요한 경우 구현을 제공하는 것입니다. 그러나 일단 게시되면 기존 구현을 중단하지 않고 인터페이스에 메소드를 추가 할 수 없습니다.기본 메소드의 이점은 이제 인터페이스에 새 기본 메소드를 추가 할 수 있으며 구현을 중단하지 않는다는 것입니다.
AbstractList::forEach
던집니다 UnsupportedOperationException
.
이 기사 에서 설명했듯이
Java 8의 추상 클래스와 인터페이스
기본 메소드를 도입 한 후 인터페이스와 추상 클래스가 동일한 것 같습니다. 그러나 Java 8에서는 여전히 다른 개념입니다.
추상 클래스는 생성자를 정의 할 수 있습니다. 그것들은 더 구조적이고 그들과 관련된 상태를 가질 수 있습니다. 대조적으로, 기본 메소드는 특정 구현 상태를 참조하지 않고 다른 인터페이스 메소드를 호출하는 측면에서만 구현 될 수 있습니다. 따라서 서로 다른 목적으로 사용하고 두 가지 중에서 선택하는 것은 실제로 시나리오 상황에 따라 다릅니다.
의 검색어에 대해
그렇다면 언제 기본 메소드와의 인터페이스를 사용해야하고 언제 추상 클래스를 사용해야합니까? 해당 시나리오에서 추상 클래스가 여전히 유용합니까?
자바 문서 는 완벽한 답변을 제공합니다.
인터페이스와 비교 한 추상 클래스 :
추상 클래스는 인터페이스와 유사합니다. 인스턴스화 할 수 없으며 구현 여부에 관계없이 선언 된 여러 메소드를 포함 할 수 있습니다.
그러나 추상 클래스를 사용하면 정적 및 최종이 아닌 필드를 선언하고 공개, 보호 및 개인 콘크리트 메소드를 정의 할 수 있습니다.
인터페이스를 사용하면 모든 필드가 자동으로 공개, 정적 및 최종이며, 선언하거나 정의한 모든 메소드 (기본 메소드)는 공개입니다. 또한 추상적이든 아니든 하나의 클래스 만 확장 할 수 있지만 여러 인터페이스를 구현할 수 있습니다.
이들 각각의 사용 사례는 아래 SE 게시물에 설명되어 있습니다.
해당 시나리오에서 추상 클래스가 여전히 유용합니까?
예. 그들은 여전히 유용합니다. 그들은 비 정적이 아닌 마지막 방법을 포함 할 수 있습니다 및 특성 ( 보호, 공공뿐만 아니라 민간 에도 자바-8 인터페이스)로 이용 가능합니다.
추상 클래스와 인터페이스를 선택할 때마다 항상 (거의) 기본 (수비수 또는 가상 확장이라고도 함) 방법을 선호해야합니다.
Collection and AbstractCollection
입니다. 이제 기본 기능을 제공하기 위해 인터페이스 자체에서 메소드를 구현해야합니다. 인터페이스를 구현하는 클래스는 메소드를 대체하거나 기본 구현을 상속하도록 선택할 수 있습니다.기본 방법의 또 다른 중요한 용도는 interface evolution
입니다. 내가 다음과 같이 공을 가지고 있다고 가정 해보십시오.
public class Ball implements Collection { ... }
이제 Java 8에서는 새로운 기능이 도입되었습니다. stream
인터페이스에 추가 된 메소드 를 사용하여 스트림을 얻을 수 있습니다 . stream
기본 방법이 아닌 경우 Collection
인터페이스에 대한 모든 구현은이 새로운 방법을 구현하지 않기 때문에 실패했을 것입니다. 기본이 아닌 메소드를 인터페이스에 추가하는 것은 아닙니다 source-compatible
.
그러나 클래스를 다시 컴파일하지 않고이 클래스를 포함하는 오래된 jar 파일을 사용한다고 가정 해보십시오 Ball
. 이 누락 된 메소드없이 클래스가 정상적으로로드되고 인스턴스를 만들 수 있으며 모든 것이 잘 작동하는 것 같습니다. 그러나 프로그램이 stream
인스턴스를 호출하면 메소드를 Ball
얻습니다 AbstractMethodError
. 따라서 방법을 기본값으로 설정하면 두 가지 문제가 해결되었습니다.
Java 인터페이스의 기본 메소드로 인터페이스 진화 가능 합니다.
기존 인터페이스가 제공되는 경우, 이전 버전의 인터페이스와의 이진 호환성을 유지하면서 메소드를 추가하려면 기본 또는 정적 메소드를 추가하십시오. 실제로, 인터페이스에 추가 된 추상 메소드는이 인터페이스를 구현하는 클래스 또는 인터페이스에 의해 구현되어야합니다.
정적 메소드는 클래스에 고유합니다. 기본 메소드는 클래스 인스턴스에 고유합니다.
기존 인터페이스에 기본 메소드를 추가하면이 인터페이스를 구현하는 클래스와 인터페이스가이를 구현할 필요가 없습니다. 그들은 할 수있다
여기 에서 주제에 대한 추가 정보 .
오래된 질문이지만 그것에 대한 의견도 제시하겠습니다.
추상 클래스 : 추상 클래스 내에서 우리는 자식 클래스에 필요한 인스턴스 변수를 선언 할 수 있습니다
인터페이스 : 인터페이스 내에서 모든 변수는 항상 공개 정적이며 인스턴스 변수를 선언 할 수 없습니다
추상 클래스 : 추상 클래스는 객체의 상태에 대해 이야기 할 수 있습니다
인터페이스 : 인터페이스는 객체 상태에 대해 이야기 할 수 없습니다
추상 클래스 : 추상 클래스 내부에서 생성자를 선언 할 수 있습니다
인터페이스 : 인터페이스 내에서 생성자의 목적은
인스턴스 변수를 초기화하는 것이므로 생성자를 선언 할 수 없습니다 . 인터페이스에 인스턴스 변수를 가질 수없는 경우 생성자가 필요합니다 .
추상 클래스 : 추상 클래스 내부에서 인스턴스와 정적 블록을 선언 할 수 있습니다
인터페이스 : 인터페이스는 인스턴스 및 정적 블록을 가질 수 없습니다.
추상 클래스 : 추상 클래스는 람다 식을 참조 할 수 없습니다
인터페이스 : 단일 추상 메소드가있는 인터페이스는 람다 식을 참조 할 수 있음
추상 클래스 : 안에서 OBJECT CLASS 메소드를 재정의 할 수 있습니다
인터페이스 : 인터페이스 내에서 OBJECT CLASS 메소드를 대체 할 수 없습니다.
나는 다음과 같은 메모로 끝날 것이다.
인터페이스의 기본 메소드 개념 / 정적 메소드 개념은 구현 클래스를 저장하기위한 것이지만 의미있는 유용한 구현을 제공하지는 않았습니다. 기본 메소드 / 정적 메소드는 일종의 더미 구현입니다. "원하는 경우 또는 구현 클래스에서 기본 메소드의 경우 메소드를 대체 할 수 있습니다" 인터페이스의 새 메소드가있을 때마다 구현 클래스에서 새 메소드를 구현하지 않아도 추가됩니다. 따라서 인터페이스는 절대 추상 클래스와 같을 수 없습니다.
Remi Forax 규칙은 추상 클래스로 디자인하지 않는다는 것입니다. 인터페이스를 사용하여 앱을 디자인합니다 . Watever는 언어에 관계없이 Java 버전입니다. 그것은 지원을받습니다 I의 nterface의 분리 원칙 에 SOL I D의 원칙.
나중에 추상 클래스를 사용하여 코드를 분해 할 수 있습니다. 이제 Java 8을 사용하면 인터페이스에서 직접 수행 할 수 있습니다. 이것은 더 이상 시설이 아닙니다.
언제 기본 메소드와의 인터페이스를 사용해야하고 언제 추상 클래스를 사용해야합니까?
이전 버전과의 호환성 : 인터페이스가 수백 개의 클래스로 구현되고 인터페이스를 수정하면 인터페이스를 구현하는 다른 많은 클래스에 필수적인 것은 아니지만 모든 사용자가 새로 추가 된 메소드를 강제로 실행한다고 상상해보십시오 . 될 기능적 인터페이스
사실 및 제한 사항 :
1- 클래스 또는 추상 클래스가 아닌 인터페이스 내에서만 선언 될 수 있습니다.
2- 몸을 제공해야 함
3- 인터페이스에서 사용되는 다른 일반적인 방법과 같이 추상적이라고 가정하지 않습니다.
Java 8에서 인터페이스는 다음과 같은 차이점이 있지만 추상 클래스처럼 보입니다.
1) 추상 클래스는 클래스이므로 Java의 인터페이스에 대한 다른 제한으로 제한되지 않습니다. 예를 들어 추상 클래스 는 상태를 가질 수 있습니다. state를 가질 수 있지만 Java 인터페이스의 상태는 가질 수 없습니다.
2) 기본 메소드가있는 인터페이스와 추상 클래스의 또 다른 의미 차이는 추상 클래스 안에 생성자를 정의 할 수 있지만 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의 나쁜 기능입니다. 나쁜 디자인, 나쁜 아키텍처, 낮은 소프트웨어 품질을 권장합니다. 기본 방법을 완전히 사용하지 않는 것이 좋습니다.
몇 가지 질문을 해보십시오. 왜 메소드를 추상 클래스에 넣을 수 없습니까? 그런 다음 둘 이상의 추상 클래스가 필요합니까? 그런 다음 반원이 무엇을 책임 지는지 생각해보십시오. 단일 클래스에 넣을 모든 메소드가 실제로 동일한 목적을 달성한다고 확신합니까? 여러 목적을 구분 한 다음 각 목적에 따라 클래스를 여러 클래스로 분할 할 수 있습니다.