Skip to content

Instantly share code, notes, and snippets.

@kkd927
Created November 30, 2017 07:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kkd927/bb01e3b7815841ce8f28c8957f1db8ea to your computer and use it in GitHub Desktop.
Save kkd927/bb01e3b7815841ce8f28c8957f1db8ea to your computer and use it in GitHub Desktop.
람다와 인터섹션 타입을 이용한 동적인 기능확장법
import java.util.function.Consumer;
import java.util.function.Function;
/**
* @see <a href="https://www.youtube.com/watch?v=PQ58n0hk7DI">토비의 봄 TV 4회 (2) Generics에서 와일드카드 활용법, 람다와 인터섹션 타입을 이용한 동적인 기능확장법</a>
*/
public class IntersectionType {
interface Pair<T> {
T getFirst();
T getSecond();
void setFirst(T first);
void setSecond(T second);
}
static class Name implements Pair<String> {
private String firstName;
private String lastName;
public Name(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
@Override
public String getFirst() {
return this.firstName;
}
@Override
public String getSecond() {
return this.lastName;
}
@Override
public void setFirst(String first) {
this.firstName = first;
}
@Override
public void setSecond(String second) {
this.lastName = second;
}
}
interface ForwardingPair<T> extends DelegateTo<Pair<T>>, Pair<T> {
default T getFirst() { return delegate().getFirst(); }
default T getSecond() { return delegate().getSecond(); }
default void setFirst(T first) { delegate().setFirst(first); }
default void setSecond(T second) { delegate().setSecond(second); }
}
interface DelegateTo<T> {
T delegate();
}
private static <T extends DelegateTo<S>, S> void run(T t, Consumer<T> consumer) {
consumer.accept(t);
}
interface Convertable<T> extends DelegateTo<Pair<T>> {
default void convert(Function<T, T> mapper) {
Pair<T> pair = delegate();
pair.setFirst(mapper.apply(pair.getFirst()));
pair.setSecond(mapper.apply(pair.getSecond()));
}
}
interface Printable<T> extends DelegateTo<Pair<T>> {
default void print() {
System.out.println(delegate().getFirst() + " " + delegate().getSecond());
}
}
public static void main(String[] args) {
Pair<String> name = new Name("Lewis", "John");
run((ForwardingPair<String> & Convertable<String> & Printable<String>)() -> name, o -> {
o.print(); // Lewis John
o.convert(String::toUpperCase);
o.print(); // LEWIS JOHN
o.convert(s -> s.substring(0, 2));
o.print(); // LE JO
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment