애매한 잡학사전

[자바8] 인터페이스 java 8 interface - 2장 본문

DEV/JAVA

[자바8] 인터페이스 java 8 interface - 2장

거대한 개발자 2022. 1. 27. 14:54
반응형
'카이 호스트만의 코어 자바 8'을 기준으로 정리하였습니다.

 

 

[자바8] 인터페이스 java 8 interface - 1장

'카이 호스트만의 코어 자바 8'을 기준으로 정리하였습니다. 인터페이스 (interface) - 객체지향 개발 5대 원칙 (SOLID) 을 지켜줄 수 있는 도구 - 개발 소스 코드의 수정을 최소화 하고 유지보수성을

dev-gabriel.tistory.com

 

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 인터페이스는 타입 파라미터를 받는다.

예를 들면 String 클래스는 Comparable&amp;amp;lt;String&amp;amp;gt;을 구현한다.
String의 오버라이딩한 compareTo 메서드

- 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

 

 

객체지향 개발 5대 원칙 (SOLID)

모든 개발이 그렇듯 프로젝트 초반에는 완벽하게 설계가 된것 같고 견고하게 구조를 다듬어 나아가는듯하게 개발이 되지만 개발을 하면 할수록 나의 코드와 구조의 틀이 점점 어긋나기 시작합

velog.io

 

 

자바 인터페이스(Java Interface)는 무엇인가?

개요 "자바 인터페이스(Java Interface)는 무엇인가?" 이런 궁금점을 가지고 있는 Java Programmer가 많습니다. 저는 "객체 지향 개발 5대 원칙 - SOLID"을 만족시켜줄 수 있어서라고 생각합니다. 그러면 "왜

interconnection.tistory.com


 

 

Comments