interface enhancements java 8 java functional interface
이 자습서에서는 Java 8의 인터페이스에 대한 추가 사항과 인터페이스를 사용하여 추상 클래스, 확장 키워드 등과 같은 Java 개념 간의 차이점을 설명합니다.
우리는 자바의 인터페이스 지난 튜토리얼에서. 다중 인터페이스를 포함하여 Java 인터페이스의 기본 개념을 소개하고 다루었습니다.
Java 8 이전에는 인터페이스에 추상 메서드와 정적 및 최종 변수 만 허용되었습니다. 추상 메서드는 기본적으로 공용이며 인터페이스를 구현하는 클래스에서 재정의해야합니다.
따라서 인터페이스는 주로 계약이었으며 상수 (정적 및 최종) 및 추상 메서드에만 관련되었습니다.
=> 여기에서 Java Beginners Guide를 살펴보십시오.
학습 내용 :
Java 8의 인터페이스 변경
Java 8 릴리스는 인터페이스에 정적 및 기본 메소드를 도입하거나 허용합니다. 인터페이스에서 기본 메소드를 사용하여 개발자는 인터페이스에 더 많은 메소드를 추가 할 수 있습니다. 이렇게하면 인터페이스를 구현하는 클래스를 방해하거나 변경하지 않습니다.
Java 8에서는 인터페이스가 정적 메소드를 가질 수도 있습니다. 정적 메서드는 클래스에서 정의한 메서드와 동일합니다. 인터페이스를 구현하는 클래스는 정적 메서드를 재정의 할 수 없습니다.
인터페이스에 정적 및 기본 메서드가 도입되어 문제없이 인터페이스를 쉽게 변경할 수 있으며 인터페이스를 구현하기가 더 쉬워졌습니다.
Java 8은 기능 인터페이스 내에 'Lambda 표현식'도 도입했습니다. 게다가, Java 8부터는 Java에 더 많은 내장 기능 인터페이스가 추가되었습니다.
이 튜토리얼에서는 Java 8의 인터페이스에 대한 이러한 모든 추가 사항에 대해 설명하고 인터페이스를 사용하는 추상 클래스, 키워드 확장 등과 같은 다양한 Java 개념 간의 차이점에 대해서도 설명합니다.
Java 인터페이스의 정적 메서드
인터페이스는 정의를 가질 수있는 메소드도 가질 수 있습니다. 인터페이스의 정적 메서드입니다. 정적 메서드는 인터페이스 내부에서 정의되며이 인터페이스를 구현하는 클래스에서 재정의하거나 변경할 수 없습니다.
인터페이스 이름을 직접 사용하여 이러한 정적 메서드를 호출 할 수 있습니다.
다음 예제는 정적 메서드의 사용을 보여줍니다.
//interface declaration interface TestInterface { // static method definition static void static_print() { System.out.println('TestInterface::static_print ()'); } // abstract method declaration void nonStaticMethod(String str); } // Interface implementation class TestClass implements TestInterface { // Override interface method @Override public void nonStaticMethod(String str) { System.out.println(str); } } public class Main{ public static void main(String() args) { TestClass classDemo = new TestClass(); // Call static method from interface TestInterface.static_print(); // Call overridden method using class object classDemo.nonStaticMethod('TestClass::nonStaticMethod ()'); } }
산출:
위의 프로그램에는 TestInterface가 있습니다. 'static_print'라는 정적 메서드와 nonstaticmethod라는 비 정적 메서드도 있습니다.
TestClass에서 TestInterface를 구현하고 nonStaticMethod를 재정의했습니다. 그런 다음 main 메서드에서 TestInterface를 사용하여 static_print 메서드를 직접 호출하고 TestClass의 개체를 사용하여 nonStaticMethod를 호출합니다.
인터페이스 기본 방법
이미 언급했듯이 Java 8 이전의 인터페이스는 추상 메서드 만 허용했습니다. 그런 다음이 메서드 구현을 별도의 클래스에 제공합니다. 인터페이스에 새 메소드를 추가해야한다면 동일한 클래스에 구현 코드를 제공해야합니다.
따라서 인터페이스에 메서드를 추가하여 인터페이스를 변경하면 구현 클래스도 변경됩니다.
이 제한은 인터페이스가 기본 메소드를 가질 수있는 Java 8 버전으로 극복되었습니다. 기본 메소드는 기존 인터페이스와의 역 호환성을 제공하며 구현 클래스를 변경할 필요가 없습니다. 기본 방법은 '가상 확장 방법'또는 '방어 방법'이라고도합니다.
기본 메서드는 선언에서 'default'키워드를 사용하여 선언됩니다. 선언 다음에는 메서드 정의가 이어집니다. 인터페이스를 구현하는 클래스에서 사용할 수있는 기본 메서드를 재정의 할 수 있습니다.
같은 방식으로 인터페이스에서 직접 구현 클래스 객체를 사용하여 재정의하지 않고 호출 할 수 있습니다.
interface TestInterface { // abstract method public void cubeNumber(int num); // default method default void print() { System.out.println('TestInterface :: Default method'); } } class TestClass implements TestInterface { // override cubeNumber method public void cubeNumber(int num) { System.out.println('Cube of given number ' + num+ ':' + num*num*num); } } class Main{ public static void main(String args()) { TestClass obj = new TestClass(); obj.cubeNumber(5); // call default method print using class object obj.print(); } }
산출:
위의 Java 프로그램은 인터페이스의 기본 메소드를 보여줍니다. 메인 메소드에서 클래스 객체를 사용하여 인터페이스의 기본 메소드를 호출 할 수 있습니다. 이는 클래스가 인터페이스를 구현하기 때문에 기본 메서드도 클래스에 사용할 수 있기 때문입니다.
노트 : 구현 클래스에서도 print () 메서드를 재정의 할 수 있습니다. 재정의되면 기본 메서드의 액세스 수정자가 구현 클래스에서 public으로 변경됩니다.
기본 방법 및 다중 상속
여러 인터페이스의 경우 각 인터페이스에 동일한 프로토 타입의 기본 메소드가있을 수있는 상황이 발생할 수 있습니다. 이러한 경우 컴파일러는 호출 할 메서드를 알지 못합니다.
기본 메서드가 모든 인터페이스에서 동일한 프로토 타입을 갖는 이러한 상황이 발생하면 솔루션은 구현 클래스의 메서드를 재정 의하여 구현 클래스 개체가 기본 메서드를 호출 할 때 컴파일러가 클래스에서 구현 된 메서드를 호출하도록하는 것입니다. .
다음 Java 프로그램은 다중 인터페이스에서 기본 메소드 사용을 보여줍니다.
//Interface_One interface Interface_One{ //defaultMethod default void defaultMethod(){ System.out.println('Interface_One::defaultMethod'); } } //Interface_Two interface Interface_Two{ //defaultMethod default void defaultMethod(){ System.out.println('Interface_Two::defaultMethod'); } } class TestExample implements Interface_One, Interface_Two{ public void disp(String str){ System.out.println('String is: '+str); } //override defaultMethod to take care of the ambiguity public void defaultMethod(){ System.out.println('TestExample::defaultMethod'); } } class Main{ public static void main(String() args) { TestExample obj = new TestExample(); //call the default method obj.defaultMethod(); } }
산출:
위의 프로그램에서 우리는 구현 클래스에서 기본 메소드 (두 인터페이스에서 동일한 프로토 타입을 가지고 있음)를 재정의했습니다. 이렇게하면 구현 클래스의 객체를 사용하여 기본 메서드에서 기본 메서드를 호출 할 때 재정의 된 메서드가 호출됩니다.
Java 8 기능 인터페이스
기능적 인터페이스는 하나의 추상 메서드 만있는 인터페이스입니다. 기본 및 정적 메서드를 여러 개 포함 할 수 있지만 포함 된 추상 메서드는 정확히 하나입니다. 또한 기능적 인터페이스는 객체 클래스 메서드의 선언을 가질 수 있습니다.
기능적 인터페이스는“ 단일 추상 메서드 인터페이스 ”또는“ SAM 인터페이스 ”. SAM 인터페이스는 Java의 새로운 기능입니다.
Java 프로그램에서 기능 인터페이스의 존재는 다음을 사용하여 표시됩니다. @FunctionalInterface 주석. 컴파일러가이 주석을 발견하면이 주석을 따르는 인터페이스가 작동한다는 것을 알게됩니다. 따라서 하나 이상의 추상 메서드가 포함 된 경우 오류가 깜박입니다.
주석 @FunctionalInterface 그러나 Java에서는 필수가 아닙니다.
다음 프로그램은 Java의 기능 인터페이스를 보여줍니다.
//declare a functional interface @FunctionalInterface //annotation indicates it’s a functional interface interface function_Interface{ void disp_msg(String msg); // abstract method // Object class methods. int hashCode(); String toString(); boolean equals(Object obj); } //implementation of Functional Interface class FunctionalInterfaceExample implements function_Interface{ public void disp_msg(String msg){ System.out.println(msg); } } class Main{ public static void main(String() args) { //create object of implementation class and call method FunctionalInterfaceExample finte = new FunctionalInterfaceExample(); finte.disp_msg('Hello, World!!!'); } }
산출:
위 프로그램의 기능적 인터페이스에는 하나의 추상 메서드가 있으며 hashCode, toString 및 equals와 같은 객체 클래스 메서드 선언도 있습니다. 이 인터페이스를 구현하는 클래스에서 추상 메서드가 재정의됩니다. 메인 메소드에서 구현 클래스의 객체를 생성하고 메소드를 사용합니다.
xml 파일을 보는 방법
Runnable 및 Comparable과 같은 인터페이스는 Java에서 제공되는 기능적 인터페이스의 예입니다. Java 8을 사용하면 기능 인터페이스 객체에 람다 표현식을 할당 할 수 있습니다.
다음 예제 프로그램은이를 보여줍니다.
class Main{ public static void main(String args()) { // use lambda expression to create the object new Thread(()-> {System.out.println('New thread created with functional interface');}).start(); } }
산출:
Java 8은 또한 java.util.function 패키지에 많은 내장 기능 인터페이스를 제공합니다.
이러한 기본 제공 인터페이스는 아래에 설명되어 있습니다.
# 1) 술어
이것은 단일 추상 메서드 테스트가있는 Java의 기능적 인터페이스입니다. 'test'메서드는 지정된 인수를 테스트 한 후 부울 값을 반환합니다.
다음은 Predicate 인터페이스의 테스트 메서드에 대한 프로토 타입입니다.
public interface Predicate { public boolean test(T t); }
# 2) BinaryOperator
BinaryOperator 인터페이스는 두 개의 인수를 받아들이고 인수와 동일한 유형의 결과 값을 반환하는 추상 메서드 'apply'를 제공합니다.
accept 메소드의 프로토 타입은 다음과 같습니다.
public interface BinaryOperator { public T apply (T x, T y); }
# 3) 기능
Function 인터페이스는 'apply'라는 추상 메서드도있는 기능 인터페이스입니다. 그러나이 적용 메소드는 T 유형의 단일 인수를 취하고 R 유형의 값을 리턴합니다.
apply 메소드의 프로토 타입은 다음과 같습니다.
public interface Function { public R apply(T t); }
다음 Java 프로그램은 위의 내장 기능 인터페이스 술어를 보여줍니다.
import java.util.*; import java.util.function.Predicate; class Main { public static void main(String args()) { // create a list of strings List names = Arrays.asList('Karen','Mia','Sydney','Lacey','Megan'); // declare string type predicate and use lambda expression to create object Predicate p = (s)->s.startsWith('M'); System.out.println('Names starting with M:'); // Iterate through the list for (String st:names) { // test each entry with predicate if (p.test(st)) System.out.println(st); } } }
산출:
위의 프로그램에서 볼 수 있듯이 문자열 목록이 있습니다. 기능적 인터페이스 Predicate를 사용하여 문자열의 항목이 M으로 시작하는지 테스트하고 M으로 시작하면 이름을 인쇄합니다.
Java의 클래스 대 인터페이스
클래스와 인터페이스는 구문이 비슷하기 때문에 비슷하지만이 두 항목은 유사점보다 더 많은 차이점이 있습니다.
Java에서 클래스와 인터페이스의 차이점을 몇 가지 나열 해 보겠습니다.
수업 | 상호 작용 |
---|---|
클래스에서 개체를 인스턴스화하고 만들 수 있습니다. | 인터페이스는 인스턴스화 할 수 없습니다. |
'class'키워드는 클래스를 만드는 데 사용됩니다. | 인터페이스는 키워드 '인터페이스'를 사용하여 생성됩니다. |
클래스는 Java에서 다중 상속을 지원하지 않습니다. | 인터페이스는 Java에서 다중 상속을 지원합니다. |
클래스에는 생성자가 포함됩니다. | 인터페이스에는 생성자가 없습니다. |
클래스는 추상 메서드를 포함 할 수 없습니다. | 인터페이스에는 추상 메서드 만 포함됩니다. |
클래스에는 기본, 공용, 개인 또는 보호 된 변수 및 메서드가있을 수 있습니다. | 인터페이스에는 기본적으로 공용 변수와 메서드 만 있습니다. |
비 액세스 수정자를 클래스의 변수와 연관시키는 것은 필수가 아닙니다. | 인터페이스는 정적 또는 최종 변수를 가질 수 있습니다. |
클래스에서 다른 클래스를 상속 할 수 있습니다. | 인터페이스에서 클래스를 상속 할 수 없습니다. |
클래스는 키워드 '확장'을 사용하여 상속 될 수 있습니다. | 인터페이스는 'implements'키워드를 사용하여 다른 클래스에서 구현할 수 있습니다. 'extends'키워드를 사용하여 다른 인터페이스에서 상속 할 수 있습니다. |
자바 확장 대 구현
‘확장’ | '구현' |
---|---|
인터페이스는 정적 및 최종 비 액세스 수정 자만 지원합니다. | Abstract는 static, final, non-static 및 non-final과 같은 모든 비 접근 수정자를 지원합니다. |
클래스는 'extends'키워드를 사용하여 다른 클래스에서 상속합니다. | 'implements'키워드는 클래스에서 인터페이스를 구현하는 데 사용됩니다. |
다른 클래스를 상속하는 클래스는 부모 클래스의 모든 메서드를 재정의 할 수도 있고 그렇지 않을 수도 있습니다. | 인터페이스를 구현하는 클래스는 인터페이스의 모든 추상 메서드를 재정의해야합니다. |
extends 키워드를 사용하여 한 번에 하나의 클래스 만 확장 할 수 있습니다. | 'implements'키워드를 사용하여 여러 인터페이스를 구현할 수 있습니다. |
인터페이스는 'extends'키워드를 사용하여 다른 인터페이스를 확장 할 수 있습니다. | 인터페이스는 '구현'키워드를 사용하여 다른 인터페이스를 구현할 수 없습니다. |
Java에서 클래스 구현 인터페이스를 추상화 할 수 있음
예, 추상 클래스는 'implements'키워드를 사용하여 인터페이스를 구현할 수 있습니다. 추상 클래스가 모든 인터페이스 추상 메서드를 구현할 필요는 없습니다. 그러나 전반적으로 모든 추상 메서드와 인터페이스를 갖고이 인터페이스를 구현하는 추상 클래스와 구체적인 클래스를 갖는 것이 좋은 디자인 관행입니다.
다음은 Java에서 이러한 구현의 예입니다.
여기서 java.util.List는 인터페이스입니다. 이 인터페이스는 java.util.AbstractList에 의해 구현됩니다. 그런 다음이 AbstractList 클래스는 LinkedList와 ArrayList라는 두 개의 구체적인 클래스에 의해 확장됩니다.
LinkedList 및 ArrayList 클래스가 List 인터페이스를 직접 구현했다면 List 인터페이스의 모든 추상 메서드를 구현해야합니다.
그러나이 경우 AbstractList 클래스는 List 인터페이스의 메서드를 구현하여 LinkedList 및 ArrayList에 전달합니다. 따라서 여기서 우리는 인터페이스에서 유형을 선언하고 공통 동작을 구현하는 추상 클래스 유연성의 이점을 얻습니다.
Java에서 추상 클래스 및 인터페이스를 사용하는 경우
우리는 주로 추상 클래스를 사용하여이 추상 클래스에서 확장되는 자식 클래스의 기본 또는 공통 동작을 정의합니다. 인터페이스는 애플리케이션에서 상호 작용하는 두 시스템 간의 계약을 정의하는 데 사용됩니다.
특정 상황은 사용할 인터페이스와 추상 클래스를 사용해야 만 해결할 수있는 특정 문제에 이상적입니다. 이 섹션에서는 인터페이스를 사용할 수있는시기와 추상 클래스를 사용할 수있는시기에 대해 설명합니다.
인터페이스를 사용하는 경우 :
- 인터페이스는 주로 구현할 작은 간결한 기능이있을 때 사용됩니다.
- API를 구현할 때 한동안 변경되지 않을 것이라는 것을 알고 있으면 그 때 인터페이스로 이동합니다.
- 인터페이스를 통해 다중 상속을 구현할 수 있습니다. 따라서 애플리케이션에서 다중 상속을 구현해야 할 때 인터페이스를 사용합니다.
- 다양한 개체가있을 때 다시 인터페이스가 더 나은 선택입니다.
- 또한 관련없는 많은 클래스에 공통 기능을 제공해야하는 경우에도 여전히 인터페이스가 사용됩니다.
추상 클래스를 사용하는 경우 :
- 추상 클래스는 주로 응용 프로그램에서 상속을 사용해야 할 때 사용됩니다.
- 인터페이스가 공용 메서드와 변수를 처리하므로 프로그램에서 공용이 아닌 액세스 수정자를 사용할 때마다 추상 클래스를 사용합니다.
- 새 메소드를 추가해야하는 경우 인터페이스보다 추상 클래스에서 수행하는 것이 좋습니다. 인터페이스에 새 메소드를 추가하면 인터페이스에 메소드 프로토 타입 만 있고 인터페이스를 사용하는 클래스 구현이 구현을 제공하므로 전체 구현이 변경되기 때문입니다.
- 다른 버전의 구성 요소를 개발하려면 추상 클래스로 이동합니다. 추상 클래스를 더 쉽게 변경할 수 있습니다. 그러나 인터페이스는 변경할 수 없습니다. 새 버전을 원하면 전체 인터페이스를 다시 작성해야합니다.
- 모든 구성 요소에 대한 공통 구현을 제공하려면 추상 클래스가 최선의 선택입니다.
Java의 인터페이스 대 추상 클래스
다음은 Java에서 Interfaces와 Abstract 클래스의 차이점 중 일부입니다.
상호 작용 | 추상 클래스 |
---|---|
인터페이스는 'interface'키워드를 사용하여 선언됩니다. | 추상 클래스는 'abstract'키워드를 사용하여 선언됩니다. |
인터페이스는 'implements'키워드를 사용하여 구현할 수 있습니다. | 초록은 '확장'키워드를 사용하여 상속 할 수 있습니다. |
인터페이스는 클래스를 확장하거나 인터페이스를 구현할 수 없으며 다른 인터페이스 만 확장 할 수 있습니다. | 추상 클래스는 클래스를 확장하거나 여러 인터페이스를 구현할 수 있습니다. |
인터페이스 멤버는 공개 만 가능합니다. | 추상 클래스 멤버는 public, private 또는 protected 일 수 있습니다. |
구현을 제공하는 데 인터페이스를 사용할 수 없습니다. 선언으로 만 사용할 수 있습니다. | 인터페이스 구현에 추상 클래스를 사용할 수 있습니다. |
인터페이스를 사용하여 다중 상속을 수행 할 수 있습니다. | 추상 클래스는 다중 상속을 지원하지 않습니다. |
인터페이스에는 추상 메서드 만있을 수 있습니다. Java 8부터 정적 및 기본 메소드를 가질 수 있습니다. | 추상 클래스는 추상 또는 비추 상 메서드를 가질 수 있습니다. |
자바의 열거 형 상속
Java의 데이터 유형에 대한 논의에서 열거 형 데이터 유형에 대해 논의했습니다. 모든 열거 형은 java.lang.Enum 클래스에서 확장됩니다. 이 클래스 java.lang.Enum은 추상 클래스입니다.
또한 Java의 모든 열거 형 클래스는 기본적으로 '최종'입니다. 따라서 열거 형 클래스에서 클래스를 상속하려고하면 컴파일러 오류가 발생합니다.
Java는 다중 상속을 허용하지 않으므로 enum 클래스는 이미 java.lang.Enum에서 상속하므로 다른 클래스에서 enum 클래스를 상속 할 수 없습니다. 그러나 enum 클래스는 Java에서 인터페이스를 구현할 수 있으며이를 Java에서 Enum 상속이라고합니다.
다음은 Java의 Enum Inheritance의 예입니다.
//WeekDays interface declaration interface WeekDays { public void displaydays(); } //enum class implementing WeekDays interface enum Days implements WeekDays { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY,FRIDAY, SATURDAY; public void displaydays() { //Override displaydays method System.out.println('The day of the week: ' + this); } } class Main { public static void main(String() args) { Days.MONDAY.displaydays(); //access enum value } }
산출:
여기에는 추상 메서드 프로토 타입 displaydays ()가있는 WeekDays 인터페이스가 있습니다. 그런 다음 WeekDays 인터페이스를 구현하는 열거 형 클래스 Days를 정의합니다. 여기에서 SUNDAY에서 SATURDAY까지 열거 형 값을 정의하고 displaydays 메서드도 재정의합니다.
마지막으로 main 메소드에서 열거 형 값에 액세스하여 표시합니다.
자주 묻는 질문
Q # 1) 인터페이스에서 메소드 본문을 제공하면 어떻게됩니까?
대답: Java 8 이전의 Java 버전의 경우 메서드 본문이 인터페이스에서 허용되지 않습니다. 그러나 Java 8 이후로 인터페이스 내에서 기본 또는 정적 메서드를 정의 할 수 있습니다.
Q # 2) 인터페이스가 Java 8에서 변수를 가질 수 있습니까?
대답: static 및 final 수정자를 사용하여 Java 8에서 상수 변수를 가질 수 있습니다. 그러나 우리는 자바 인터페이스에 인스턴스 변수를 가질 수 없습니다. 인터페이스에서 인스턴스 변수를 선언하려고하면 컴파일러 오류가 발생합니다.
Q # 3) Java 8의 인터페이스 개선 사항은 무엇입니까?
대답: Java 8에서 인터페이스의 가장 중요한 개선 사항은 인터페이스에서 정적 및 기본 메소드가 허용된다는 것입니다. 메서드를 static 또는 default로 선언하고 인터페이스 내에서 정의 할 수 있습니다.
Q # 4) Java 인터페이스에서 기본 메서드를 재정의 할 수 있습니까?
대답: 아니요. 인터페이스에서 기본 방법을 재정의 할 필요는 없습니다. 이는 클래스에서 인터페이스를 구현할 때 해당 클래스의 기본 메서드가 구현 클래스에 액세스 할 수 있기 때문입니다. 따라서 구현 클래스의 객체를 사용하여 인터페이스의 기본 메서드에 액세스 할 수 있습니다.
Q # 5) 인터페이스는 Java에서 필드를 가질 수 있습니까?
대답: 예, Java의 인터페이스에 필드 또는 변수를 가질 수 있지만 기본적으로 이러한 모든 필드는 정적, 최종 및 공용입니다.
결론
이 자습서에서는 Java 8의 인터페이스 변경 사항에 대해 설명했습니다. Java 8은 인터페이스에 정적 및 기본 메서드를 도입했습니다. 이전에는 인터페이스에서 추상 메서드 만 가질 수있었습니다. 그러나 Java 8부터는 Java에서 기본 및 정적 메서드를 정의 할 수 있습니다.
또한 Java 8에서는 Java의 기능 인터페이스와 함께 람다 식을 사용할 수 있습니다. 그런 다음 추상 클래스와 인터페이스에 대해 논의하고 Java에서 각각을 사용할 때를 보았습니다. 우리는 또한 자바에서 열거 형 상속을 보았다.
또한 확장 및 구현, 클래스 및 인터페이스, 추상 클래스 및 인터페이스 등의 몇 가지 차이점에 대해 논의했습니다.