인터페이스의 예
목차
1. 인터페이스의 예
2. Comparable 인터페이스
3. Comparator 인터페이스
4. Runnable 인터페이스
5. 사용자 인터페이스 콜백
1. 인터페이스의 예
언뜻 보면 인터페이스는 많은 일을 하는 것 같지 않다. 그저 클래스가 구현을 약속하는 메서드의 집합이다. 하지만 중요하다. 자주 사용하는 네 가지 인터페이스로 인터페이스의 중요성을 살펴본다. 네 가지 인터페이스는 표준 자바 라이브러리에 들어 있는 것들이다.
2. Comparable 인터페이스
클래스가 자신이 갖고 있는 객체를 정렬하려면 Comparable 인터페이스를 구현해야 한다. 문자열대 문자열, 인스턴스 대 인스턴스로 비교해야 하므로 타입 파라미터를 받는다.
Comparable 인터페이스는 객체 간에 일반적인 정렬이 필요할 때 정렬의 기준을 정하는 compareTo 메서드를 확장해서 정의한다.
public interface Comparable<T> {
int compareTo(T other);
}
x.compareTo(y);
Employee emp1 = new Employee(1, "mike", 100.1);
Employee emp2 = new Employee(2, "john", 123.45);
Employee emp3 = new Employee(3, "seungui", 9.9);
Employee emp4 = new Employee(4, "changStar", 20000);
List<Employee> empList = new ArrayList<>();
empList.add(emp1);
empList.add(emp2);
empList.add(emp3);
empList.add(emp4);
System.out.println("리스트에 넣은 순서대로");
System.out.println(empList);
System.out.println("compareTo 메소드에 정한 순서로");
empList.sort(empList);
System.out.println(empList);
compareTo 메서드는 정수 값을 반환한다.
- 양수 : x > y
- 음수 : x < y
- 0 : 같다.
양수를 반환하면 x가 y다음에 온다. 음수 값이 오면 y가 x다음에 온다. x와 y가 같으면 반환값이 0이다.
public class Employee implements Comparable<Employee> {
...
@Override
public int compareTo(Employee other) {
return getId() - other.getId();
}
}
정수가 음수일 때 두 정수의 차이를 반환하면 메서드가 제대로 동작하지 않는다. 이럴 때는 Integer.compare 메서드를 사용한다.
부동소수점 값을 비교할 때는 정적 메서드 Double.compare를 사용해야 한다.
@Override
public int compareTo(Employee other) {
return Double.compare(getSalary(), other.getSalary());
}
3. Comparator 인터페이스
문자열을 사전 순서가 아닌 증가하는 길이 순서로 비교한다고 하자. String 클래스로는 compareTo 메서드를 다른 방법으로 구현하게 만들 수 없다. String 클래스는 우리가 소유한 클래스가 아니므로 수정할 수 없다.
Comparator 인터페이스는 객체 간의 특정한 정렬이 필요할 때, compare 메서드를 확장하여 구현한다. Compareble과 공통점은 정렬의 기준을 정한다는 것이고 차이점은 정렬 기준이 일반적이냐 특정하냐의 차이다.
public interface Comparator<T> {
int compare(T first, T second);
}
Comparator를 구현한 클래스를 사용하거나 익명 클래스를 만들어서 사용한다.
public class LengthComparator implements Comparator<String> {
@Override
public int compare(String first, String second) {
return first.length() - second.length();
}
}
// main.java
LengthComparator lengthComparator = new LengthComparator();
String word1 = "show me the moeny";
String word2 = "power overwhelming";
if(lengthComparator.compare(word1, word2) > 0) {
System.out.println("word1's length is Long");
} else {
System.out.println("hmm");
}
//익명의 Comparator를 만들기
Comparator<Employee> nameLengthComparator = new Comparator<Employee>() {
@Override
public int compare(Employee o1, Employee o2) {
return o2.getName().length() - o1.getName().length();
}
};
// 람다 표현식으로 줄이면..
// empList.sort(empList, (o1, o2) -> o2.getName().length() - o1.getName().length());
empList.sort(empList, nameLengthComparator);
System.out.println(empList);
4. Runnable 인터페이스
모든 프로세서가 멀티 코어를 장착하면서 모든 코어가 바쁘게 작업하게 되었따. 아마 특정 작업을 별도의 스레드에서 실행하거나 실행 스레드 풀에 넣으려고 할 것이다. 이렇테 테스크를 정의하려면 Runnable 인터페이스를 구현해야 한다. Runnable 인터페이스는 메서드를 하나만 갖는다.
public class HelloTask implements Runnable {
@Override
public void run() {
for(int i = 1; i < 1000; i++) {
System.out.println("Hello World~~!!!");
}
}
}
테스크를 새로운 스레드에서 실행하려면 Runnable로부터 스레드를 생성하고 해당 스레드를 시작한다.
HelloTask helloTask = new HelloTask();
Thread thread = new Thread(helloTask);
thread.start();
이제 run 메서드는 별도의 스레드에서 실행되며, 현재 스레드에서는 다른 작업을 계속할 수 있다.
5. 사용자 인터페이스 콜백
GUI에서는 사용자가 버튼 클릭, 메뉴 옵션 선택, 슬라이더 드래그 등의 액션을 했을 때 수행될 액션을 지정해야 한다. 수행될 액션을 보통 콜백이라 하는데, 사용자가 어떤 액션을 취했을 때 역으로 일부 코드가 호출되기 때문이다.
자바기반 GUI 콜백 라이브러리에서는 콜백 인터페이스를 사용한다. JavaFX에서는 이벤트를 보고할 때 다음과 같은 인터페이스를 사용한다.
public interface EventHandler<T> {
void handle(T event);
}
여기서 T는 버튼 클릭에 해당하는 ActionEvent처럼 보고할 이벤트의 타입이다.
public class CancleAction implements EventHandler<ActionEvent> {
@Override
public void handle(ActionEvent event) {
System.out.println("action!");
}
}