본문 바로가기

컴퓨터학원(복습)(수료)

자바(JAVA)기반 안드로이드 웹&앱 개발 22일차(멤버클래스, 로컬클래스, 익명클래스, 람다)

3.23(화)는 온라인 수업으로 일차에서 뺐습니다.

1. ‘멤버 클래스(Member Class)’를 언제 사용하는가?

.1) 클래스의 정의를 감추어야 할 때 유용하게 사용이 된다.

.2) 멤버 클래스가 private로 선언되면 이 클래스 정의를 감싸는 클래스 내에서만

....인스턴스 생성이 가능하다.

※ 멤버클래스(Member Class) 사용 예시

 

☞ Papers 클래스의 외부에서는 getPrinter 메소드가 어떠한 인스턴스의 참조 값을

....반환하는지 알지 못한다. 다만 반환되는 참조 값의 인스턴스가 Printable을 구현하고

....있어서 Printable의 참조변수로 참조할 수 있다는 사실만 알 뿐이다.

....이러한 상황을 ‘ 클래스의 정의가 감추어진 상황’이라고 한다.

☞ 클래스의 정의를 감추면, getPrinter 메소드가 반환하는 인스턴스가 다른 클래스의

....인스턴스로 변경되어도 Papers 클래스 외부의 코드는 조금도 수정할 필요가 없게 된다.

....(코드에 유연성 부여)

☞ 컬렉션 프레임워크의 ‘반복자(iterator)’도 이러한 원리로 사용된다.

 

1. 로컬 클래스(Local Class)

.1) 클래스의 정의 위치가 if문이나 while문 또는 메소드 몸체와 같은 블록안에 정의된다.

.2) 멤버 클래스보다도 클래스를 더 깊이, 특정 블록안으로 감추는 효과가 있다.

※ 로컬 클래스(Local Class) 사용 예시

 

☞ 메소드 내에 클래스를 정의하면 해당 메소드 내에서만 인스턴스 생성이 가능하다.

☞ 즉, 클래스에 대한 private 선언은 의미가 없다.

 

1. 익명 클래스(Anonymous Class)

※ 익명 클래스(Anonymous Class) 사용 예시

 

☞ new Printable() 다음에 바로 해당 인터페이스를 구현하고 클래스의 정의를

....덧붙이면(몸체) 인스턴스 생성이 가능하다.

※ 컬렉션 프레임워크 + 익명 클래스(Anonymous Class) 사용 예시

 

 

1. Lambda(람다)

※ 람다 변환 과정 예시(익명클래스 예시 -> 람다 예시)

 

.1) ‘람다’와 ‘익명 클래스’는 분명 다르다. 그러나 둘 다 인스턴스의 생성으로 이어지고

.....람다식이 익명 클래스의 정의를 일부 대체하기 때문에 익명 클래스의 정의를 기반으로

.....람다식을 이해하는 것도 좋은 방법이다.

.2) 람다는 인터페이스에서 추상 메소드가 하나 일 때 사용이 가능하다.

..(1) 즉, Printable prn = new Printable() 에서 new Printable()이 생성될 것은

......컴파일러가 예측할 수 있으므로 생략이 가능하다.

..(2) Printable 인터페이스에서 추상메소드가 하나만 존재하므로

......public void print(String s)도 컴파일러가 예측할 수 있으므로 생략이 가능하다.

..(3) 컴파일러가 s개 매개변수라는 사실까지는 유추하지 못한다. 따라서 이에 대한 정보를

.....남기면서, 더불어 람다식의 구분을 위해 ‘람다 연산자’라 불리는 -> 을 추가하여

.....람다식을 표현한다.

..(4) 매개변수 선언도 추상 메소드를 보면 유추가 가능하므로 생략이 가능하다.

☞ Printable prn = (String s) -> { System.out.println(s); }; // 람다식 완성

☞ Printable prn = (s) -> { System.out.println(s); };; // 조금 더 줄인 람다식

 

1. Lambda(람다)식의 인자 전달

※ Lambda(람다)식의 인자 전달 예시

 

 

1. 인스턴스보다 기능 하나가 필요한 상항을 위한 람다

.1) Comparator<T>를 구현하여, Collections.sort(list, new 기준);을 할 때가 있다. 이 때, 인스턴스를 전달하는 형태이지만 내용을 보면 메소드, 즉 기능을 전달하는 것에 해당한다. 이것을 람다식 기반으로 바꾸기 전에 밑에 몇 가지 내용을 설명하겠다.

 

.2) 매개변수가 있고 반환하지 않는 람다식

※ 매개변수가 있고 반환하지 않는 람다식 예시

 

☞ 메소드의 몸체가 하나의 문장으로 이뤄져 있다면 중괄호의 생략이 가능하다.

☞ 매개변수가 하나일 경우에는 소괄호도 생략할 수 있다.

 

.3) 매개변수가 둘이고 반환하지 않는 람다식

※ 매개변수가 둘이고 반환하지 않는 람다식 예시

 

.4) 매개변수가 있고 반환하는 람다식

※ 매개변수가 있고 반환하는 람다식 예시

 

☞ 메소드 몸체에 해당하는 내용이 return 문이면 그 문장이 하나이더라도 중괄호의 생략이

....불가하다.

☞ 메소드 몸체에 연산이 등장하는데, 이 연산이 진행되면 그 결과로 값이 남게 된다.

....그러면 이 값은 별도로 명시하지 않아도 반환의 대상이 된다.

....따라서 return 문이 메소드 몸체를 이루는 유일한 문장이면 (a, b) -> a + b 가 가능하다.

※ 매개변수가 있고 반환하는 람다식 활용 예시

 

☞ 메소드 몸체를 이루는 유일한 문장이 메소드 호출문인데, 이 문장에서 호출하는

....length는 값을 반환한다. 따라서 메소드의 호출 결과로 반환된 값이 남으므로 별도로

....명시하지 않아도 반환의 대상이 된다.

 

.5) 매개변수가 없는 람다식

..(1) 매개변수가 없는 람다식은 매개변수를 표현하는 소괄호 안을 비우면 된다.

※ 매개변수가 없는 람다식 예시

 

☞ 둘 이상의 문장으로 이뤄진 람다식은 중괄호로 반드시 감싸야 하며, 값을 반환할 때에도

.....return문을 반드시 사용해야 한다.

 

.6) 함수형 인터페이스(Functional Interfaces)와 어노테이션

..(1) 람다식은 함수형 인터페이스를 기반으로 작성이 될 수 있다.

..(2) @FunctionalInterface 는 함수형 인터페이스에 부합하는지를 확인하기 위한

......어노테이션이다.

,,(3) static, default 선언이 붙은 메소드의 정의는 함수형 인터페이스의 정의에 아무런

......영향을 미치지 않는다.

@FunctionlaInterface

interface Calculate{

....int cal(int a, int b);

....default int add(int a, int b) { return a + b; }

....static int sub(int a, int b) { return a - b; } // 함수형 인터페이스로 가능하다.

 

.7) 람다식과 제네릭

※ 람다식과 제네릭 예시

 

1. 미리 정의되어 있는 함수형 인터페이스

.1) Predicate<T> 인터페이스

..(1) boolean test(T t); : 전달된 인자를 대상으로 true, false를 판단하는 추상 메소드가

.......존재한다.

※ Predicate<T> 인터페이스 예시

 

☞ public static int sum(Predicate<Integer> p, List<Integer> lst) {...}

....☞ boolean test(Integer t) 메소드 정의에 해당하는 람다식을 작성해서 전달해야 한다.

..(2) Predicate<T>를 구체화 한 인터페이스들

...① IntPredicate : boolean test(int value)

...② LongPredicate : boolean test(long value)

,,,③ DoublePredicate : boolean test(double value)

,,,④ Bipredicate<T, U> : boolean test(T t, U u)

 

.2) Supplier<T>

..(1) T get() : 단순히 무엇인가 반환하는 추상메소드가 존재한다.

※ Supplier<T> 사용 예시

..(2) Supplier<T> 를 구체화 한 인터페이스들

...① IntSupplier : int getAsInt()

...② LongSupplier : long getAsLong()

...③ DoubleSupplier : double getAsDouble()

...④ BooleanSupplier : boolean getAsBoolean()

 

.3) Consumer<T>

..(1) void accept(T t); : 전달된 인자 기반으로 ‘반환’ 이외의 다른 결과를 보이는

......추상 메소드가 존재한다.

※ Consumer<T> 사용 예시

 

..(2) Consumer<T>를 구체화하고 다양화 한 인터페이스들

...① IntConsumer : void accept(int value)

.......ObjIntConsumer<T> : void accept(T t, int value)

...② LongConsumer : void accept(long value)

.......ObjLongConsumer<T> : void accept(T t, long value)

...③ DoubleConsumer : void accept(double value)

.......ObjDoubleConsumer<T> : void accept(T t, double value)

...④ BiConsumer<T, U> : void accept(T t, U u)

 

.4) Function<T, R>

..(1) R apply(T t) : 전달 인자와 반환 값이 모두 존재할 때 사용하는 추상메소드가 존재

※ Function<T, R> 사용 예시

 

..(2) Function<T,R>을 구체화하고 다양화 한 인터페이스들

...① IntToDouble Function : double applyAsDouble(int value)

...② DoubleToIntFunction : int applyAsInt(double value)

...③ IntUnaryOperator : int applyAsInt(int operand)

...④ DoubleUnaryOperator : double applyAsDouble(double operand)

...⑤ BiFunction<T, U, R> : R apply(T t, U u)

...⑥ IntFunction<R> : R apply(int value)

...⑦ DoubleFunction<R> : R apply(double value)

...⑧ ToIntFunction<T> : int applyAsInt(T value)

...⑨ ToDoubleFunction<T> : double applyAsDouble(T value)

...⑩ ToIntBiFunction<T, U>

...⑪ ToDoubleBiFunction<T, U>

 

.5) removeIf 메소드

..(1) 컬렉션 인스턴스에 저자오딘 인스턴스를 다음 test 메소드의 인자로 전달했을 때,

......true가 반환되는 인스턴스는 모두 삭제하는 메소드이다.

..(2) default boolean removeIf(Predicate<? super E> filter) 로 선언되어 있다.

...☞ ArrayList<Integer> 인스턴스를 생상하면 그 안에 존재하는 removeIf 메소드의 E는

...,,,,,Integer로 결정된다. 따라서 Predicate<Integer>, Predicate<Number>,

........Predicate<Object>를 메소드의 인자로 전달할 수 있다.

※ removeIf 메소드 예시