일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- naver smartEditor
- 환경구성
- AWS SQS
- Log
- 로그 데이터
- 아이비시트
- db
- Study
- 카이호스트만
- AWS Athena
- AWS Glue
- jQuery
- intellij
- AWS
- function
- 인텔리J
- #jQuery
- java8
- Git
- 환경 구성
- Java
- 자바스크립트
- 자바8
- JavaScript
- 자바
- athena
- ibsheet
- s3
- aws lambda
- aws S3
- Today
- Total
애매한 잡학사전
[자바8] 인터페이스 java 8 interface - 2장 본문
'카이 호스트만의 코어 자바 8'을 기준으로 정리하였습니다.
6. 상수
public interface SwingConstants{
[public static final] int NORTH = 1;
[public static final] int NORTH_EAST = 2;
[public static final] int EAST = 3;
...
}
- 인터페이스에 정의한 변수는 자동으로 public static final 이다.
- 인터페이스 안에는 인스턴스 변수를 둘 수 없다.
: 인터페이스는 객체의 상태가 아니라 동작을 명시한다.
7. 정적 메소드와 기본 메소드
- 자바8 이전에는 인터페이스의 모든 메서드가 추상 메서드여야 했지만 자바 8은 실제 구현이 있는 메서드를 추가할 수 있다.
7.1 정적 메서드
public static void main(String... args){
IntSequence digits = IntSequence.digitsOf(1729);
}
public interface IntSequence {
public static IntSequence digitsOf(int n) {
return new digitSequence(n);
}
}
- 기술적인 측면에서 인터페이스에 정적 메서드가 포함되지 못할 이유는 없었지만 인터페이스를 추상명세로 보는 관점에 맞지 않았다.
- 자바8 이전에는 정적 메서드를 동반 클래스(companion class)에 두었지만 자바8 이후에는 그럴 필요가 없어졌다.
( Collection/Collections, Path/Paths 등.. )
7.2 기본 메서드
public interface IntSequence {
default boolean hasNext() { return true; }
int next();
}
- default 메서드인 hasNext()는 IntSequence 인터페이스를 구현하는 클래스에서 오버라이딩 하지 않아도 구현 클래스에서 hasNext() 메서드를 사용할 수 있다.
: 오버라이딩 해서 사용할 수도 있다.
7.3 기본 메소드 충돌 해결
public interface Person {
String getName();
default int getId() { return 0; }
}
public interface Identified {
default int getId() {
return Math.abs(hashCode());
}
}
public class Employee implements Person, Identified {
...
}
- 위와 같은 두 개의 인터페이스를 Employee 클래스에서 구현할 경우 getId 메서드는 어떻게 될까?
:: Employee 클래스는 Person 인터페이스의 getId 메서드와 Identified 인터페이스의 getId 메서드를 상속 받는데 자바 컴파일러는 둘 중 하나를 우선해서 선택할 수 없어서 오류를 보고하게 된다.
pubilc class Employee implements Person, Identified {
public int getId() {
return Identified.super.getId();
}
}
- 위와 같이 충돌한 메서드 중 하나로 위임해야 하거나 Employee 클래스에서 getId 메서드를 작성하여 고유의 ID 체계를 구현해야 한다.
:: 이런 모호성을 해결하는 일은 개발자의 책임이다.
8. 많이 사용 하는 인터페이스
8.1 Comparable
public interface Comparable<T> {
int compareTo(T other);
}
- 클래스가 자신이 갖고 있는 객체를 정렬할 수 있으려면 Comparable 인터페이스를 구현해야 한다.
- Comparable 인터페이스는 문자열 대 문자열, 직원 대 직원 등으로 비교해야 한다.
따라서 Comparable 인터페이스는 타입 파라미터를 받는다.
- x.compareTo(y)를 호출하면 compareTo 메서드는 정수 값을 반환하는데 이 정수 값은 x와 y중 어느 것이 먼저 와야 하는지를 나타낸다.
: 양수값을 반환하면 x가 y다음에 오고 음수값을 반환하면 y가 x 다음에 온다. x와 y가 같으면 반환 값이 0이다.
: 정수가 음수일 때 두 정수의 차이를 반환하면 메서드가 제대로 동작하지 않는다. 이때는 Integer.compare 메서드를 사용한다.
: 부동소수점 값을 비교할 때는 정적 메서드 Double.compare를 사용해야 차이를 반환할 수 있다.
8.2 Compartor
public interface Comparator<T> {
int compare(T first, T second);
}
- 문자열을 사전 순서가 아닌 증가하는 길이 순서로 비교하려면 String 클래스로는 compareTo 메서드를 다른 방법으로 구현하게 만들 수 없다.
- 배열과 비교자(Comparator 인터페이스를 구현하는 클래스의 인스턴스)를 파라미터로 받는 Arrays.sort 메서드를 사용한다.
/* 문자열을 길이로 비교하려면 Comparator<String>을 구현하는 클래스를 정의 */
class LengthComparator implements Comparator<String> {
@Override
public int compare(String first, String second){
return first.length() - second.length();
}
}
/* 이 클래스의 인스턴스를 만들어야 한다. */
Comparator<String> comp = new LengthComparator();
if (comp.compare(words[i], words[j]) > 0) ...
- 위의 호출을 Comparable의 compareTo 메서드와 비교해 보면 compare 메서드는 비교자 객체에서 호출하고,
compareTo 메서드는 문자열 자체에서 호출한다.
String[] friends = {"Peter", "Paul", "Mary"};
Arrays.sort(friends, new LengthComparator()); // 문자열 길이별 정렬 (Comparator.compare())
/*
예상 결과 값 : ["Paul", "Mary", "Peter"] 또는 ["Mary", "Paul", "Peter"]
*/
Arrays.sort(friends); // 사전 순서별 정렬 (Comparable.compareTo())
/*
예상 결과 값 : ["Mary", "Paul", "Peter"]
*/
- Arrays.sort() 메서드에 Comparator<String> 인터페이스를 구현한 클래스를 배열과 같이 파라미터로 넘겨주게 되면 friends 배열은 길이 순으로 정렬되어 진다.
- 사전 순서별 정렬을 하려면 Comparable<String> 인터페이스를 구현한 Arrays.sort 메서드를 이용하면 된다.
8.3 Runable
public interface Runable {
void run();
}
- 특정 태스크(작업)를 별도의 스레드에서 실행하거나 실행 스레드 풀에 넣으려고 할때 태스크를 정의하려면 Runnable 인터페이스를 구현해야 한다.
class HelloTask implements Runnable {
public void run(){
for (int i=0; i < 1000; i++) {
System.out.println("Hello World!");
}
}
}
/*
위의 태스크를 새로운 스레드에서 실행하려면 Runnable로부터 스레드를 생성하고
해당 스레드를 시작해야 한다.
*/
Runnable task = new HelloTask();
Thread thread = new Thread(task);
thread.start();
[참고자료]
- 카이 호스트만의 코어 자바 8
'DEV > JAVA' 카테고리의 다른 글
[자바8] 람다 표현식 - 2장 (0) | 2022.02.15 |
---|---|
[자바8] 람다 표현식 - 1장 (0) | 2022.02.13 |
[자바8] 인터페이스 java 8 interface - 1장 (0) | 2022.01.24 |
AWS Personalize putUsers 처리 Importing users incrementally (0) | 2021.10.26 |
Java8 Portable version 만들기 (6) | 2017.12.03 |