티스토리 뷰

목차

1. 인터페이스 기본 메소드와 스태틱 메소드

2. 자바 8 API의 기본 메소드와 스태틱 메소드

 

 

1. 인터페이스 기본 메소드와 스태틱 메소드

1) default 메소드

인터페이스에서 메소드 선언이 아니라 구현체를 제공하는 방법

public interface Foo {
    void printName();
    String getName();

    // 하위 클래스가 모두 다음 메소드를 갖도록 정의
    /**
     * @implSpec
     * 이 구현체는 getName()으로 가져온 문자열을 대문자로 바꿔 출력한다.
     */
    default void printNameUpperCase() { //-- ①
        System.out.println(getName().toUpperCase(Locale.ROOT));
    }

    // Object가 제공하는 메소드는 default 메소드로 제공 불가능
//   default String toString() {
//
//    }

    // Object가 제공하는 메소드와 구현할 기능이 다른경우 선언은 가능
//    String toString();

}

-----------------
public interface Bar extends Foo {

    // 상위 인터페이스의 default 메소드를 다시 추상화
    void printNameUpperCase();
}

-----------------
public class DefaultFoo implements Foo {
    private String name;

    public DefaultFoo(String name) {
        this.name = name;
    }

    @Override
    public void printName() {
        System.out.println(name);
    }

    @Override
    public String getName() {
        return name;
    }
    
    // default 메소드를 재정의할 수 있음
    @Override
    public void printNameUpperCase() { //-- ②
        System.out.println(name.toUpperCase());
    }
}

-----------------
// main
Foo foo = new DefaultFoo("mandy");
foo.printName();
foo.printNameUpperCase(); //-- ①, ②

 

① default 메소드를 만들어 모든 하위 클래스에 제공,

    @implSpec 자바독 태그를 사용해 구현 메소드의 기능을 문서화 할 것.

② 구현 클래스에서 default 메소드를 재정의 할 수 있다.

 

인터페이스를 구현한 클래스를 깨트리지 않고 새 기능을 추가할 수 있다.

구현체가 모르게 추가된 기능으로 그만큼 리스크가 있다.

 

2) static 메소드

static 메소드는 해당 타입 관련 헬터 또는 유틸리티 메소드를 제공할 때 사용

public interface Foo {
    void printName();
    String getName();

    static void printAnythings() {
        System.out.println("Foo");
    }
}

-----------------
// main
// interface 이름으로 static 메소드 호출
Foo.printAnythings();

 

 

2. 자바 8 API의 기본 메소드와 스태틱 메소드

1) Iterable 의 기본 메소드

// 1. Iterable의 기본 메소드
List<String> names = new ArrayList<>();
names.add("mandy");
names.add("keesun");
names.add("toby");
names.add("foo");

/* (1) Iterable의 forEach default 메소드
default void forEach(Consumer<? super T> action) {
    Objects.requireNonNull(action);
    for (T t : this) {
        action.accept(t);
    }
}
 */
// 익명 클래스
names.forEach(new Consumer<String>() {
    @Override
    public void accept(String s) {
        System.out.println(s);
    }
});

// lambda
names.forEach(s -> System.out.println(s));

/*
public void println(String x) {
    synchronized (this) {
        print(x);
        newLine();
    }
}
 */
// 메소드 참조
names.forEach(System.out::println);

// (2) Iterable의 spliterator default 메소드
/*
default Spliterator<E> spliterator() {
    if (this instanceof RandomAccess) {
        return new AbstractList.RandomAccessSpliterator<>(this);
    } else {
        return Spliterators.spliterator(this, Spliterator.ORDERED);
    }
}
 */
System.out.println("------------------");
Spliterator<String> spliterator = names.spliterator();
Spliterator<String> spliterator1 = spliterator.trySplit();
Spliterator<String> spliterator2 = spliterator1.trySplit();
while (spliterator.tryAdvance(System.out::println));
System.out.println("==================");
while (spliterator1.tryAdvance(System.out::println));
System.out.println("==================");
while (spliterator2.tryAdvance(System.out::println));

Iterable <- Collection <- List <--- ArrayList 구조에서

Iterable에 정의된 default 메소드 forEach(), spliterator() 사용

 

2) Collection의 기본 메소드

// 2. Collection의 기본 메소드
List<String> names = new ArrayList<>();
names.add("mandy");
names.add("keesun");
names.add("toby");
names.add("foo");

// (1) stream
Set<String> m = names.stream().map(String::toUpperCase)
        .filter(s -> s.startsWith("m"))
        .collect(Collectors.toSet());

// (2) removeIf
names.removeIf(s -> s.startsWith("m"));
names.forEach(System.out::println);

 

3) Comparator의 기본 메소드

// 3. Comparator의 기본 메소드
List<String> names = new ArrayList<>();
names.add("mandy");
names.add("keesun");
names.add("toby");
names.add("foo");

// (1) reversed
Comparator<String> compareToIgnoreCase = String::compareToIgnoreCase;
names.sort(compareToIgnoreCase.reversed());

names.forEach(System.out::println);

 

 

 

 

출처

https://www.inflearn.com/course/the-java-java8 더 자바, Java 8(백기선)

728x90