• 내부클래스
    • 멤버내부클래스
      • 가장 일반적인 형태의 내부 클래스
      • 내부 클래스(inner class)란 하나의 클래스 내부에 선언된 또 다른 클래스를 의미
      • 서로 관련 있는 클래스를 논리적으로 묶어서 사용
    • 정적 내부 클래스 (Static Nested Class)
      • 이 클래스는 외부 클래스의 정적 멤버처럼 취급
    • 익명내부클래스
      • 이름 없이 정의되는 클래스가 어떠한 클래스 안에 존재하는 경우
      • 주로 인터페이스, 추상클래스 등 인스턴스화 할 수 없는 클래스를 익명클래스를 통해 구현하고, 객체화하기 위해 사용
  • 익명(내부)클래스
    • 다른 내부 클래스와는 달리 이름을 가지지 않는 클래스를 의미

    • 익명 클래스는 클래스의 선언과 동시에 객체를 생성

    • 기본문법 클래스이름 참조변수이름 = new 클래스이름(){

        메소드의 구현
      

      };

    • 익명 클래스는 선언과 동시에 객체를 생성하여 단 하나의 객체만을 생성하는 일회용 클래스

    • 구현해야 하는 메소드가 적은 추상클래스, 인터페이스 등을 구현할 때 사용

    • 익명클래스와 일반클래스의 추상클래스 상속 비교

      • 추상클래스 public abstract class Test1 { abstract void test(); }
      • 일반적인 상속클래스
        • 상속클래스 생성
          • public class Test2 extends Test1 { void test(){ System.out.println("hello"); } }
        • 객체 생성
          • Test2 t1 = new Test2 ();
      • 익명클래스
        • Test1 t1 = new Test1(){ @Override void test(){ System.out.println("hello");   } };
      • 일반적인 클래스와의 차이점
        • Test1 () 옆에 {}가 있고, 객체 생성과 동시에 Overide를 통해 재정의하고 있다는 것
        • 그렇다면 상속받은 새로운 클래스인 것인가?
          • 상속을 받으려면 “신규 클래스명 extends 클래스”의 구조로 신규 클래스명을 가져야함
          • 위의 소스 코드는 신규 클래스명이 존재하지 않는다.
        • Overide를 통해 재정의하게 되었으므로, 본래의 클래스도 아니고 신규 상속 클래스도 아닌, 이름이 없는 익명의 클래스가 만들어짐과 동시에 익명객체가 생성
  • 람다 표현식
    • 람다 표현식(함수)은 하나의 추상 메서드만을 가진 인터페이스(함수적 인터페이스)의 익명 구현체를 정의하는데 사용
    • 람다 표현식은 익명 클래스의 인스턴스를 생성할 때 사용되는 new 키워드 없이도, 해당 인터페이스의 익명 구현체를 간결하게 만들 수 있는 방식
    • 기본문법
      • (parameter1, parameter2, ...) -> { statements } (parameter1, parameter2, ...) -> statements
    • 익명객체방식과 람다함수(익명함수)의 비교
      • 익명객체 방식 AnonymousInterface ai = new AnonymousInterface() { @Override public void cry() { System.out.println("cry cry"); } };
      • 람다함수화(익명함수화)
        • AnonymousInterface ai2 = ()-> System.out.println("cry cry lambda”);
        • 구현할 메서드가 1개만 있으므로, java에서 알아서 해당 메서드를 인지하고 참조.
        • 그래서 () 이 부분은 cry()함수의 매개변수 부분을 의미
        • -> System.out.println("cry cry lambda”); 부분을 통해 추상메서드 구현
        • 즉, 익명클래스와 마찬가지로 이름없는 구현체를 만들되, 간결하게 함수만을 구현하여 사용
    • 람다함수(익명함수) 대표적인 사용 예시
      • Comparator
        • Comparator 인터페이스는 객체를 비교하는 데 사용되고, 주로 객체의 배열이나 컬렉션을 정렬할 때 사용
        • Comparator 인터페이스는 단 하나의 메서드, compare(T o1, T o2)를 정의
        • Comparator를 구현한 익명객체를 사용한 정렬
          • Collections.sort(players, new Comparator<Player>() { @Override public int compare(Player a, Player b) { return b.getScore() - a.getScore(); });
          • Collections.sort는 정렬대상 객체와 Comparator객체를 매개변수로 받음
        • Comparator를 구현한 익명함수(람다함수)를 사용한 정렬
          • Collections.sort(players, (a, b) -> b.getScore() - a.getScore());
  • Comparable과 Comparator
    • Comparable<T> 인터페이스
      • 비교를 위한 인터페이스
        • 자바에서 compareTo 메서드가 있는 클래스들은 모두 Comparable 인터페이스를 구현
      • Comparable의 유일한 메서드 compareTo()
        • 문자열비교
          • 서로의 문자열 유니코드의 차이값을 리턴
          • 같은 위치의 문자만 비교하기 때문에, 첫번째 문자부터 순서대로 비교
          • 첫번째가 다르다면 첫번째 문자의 차이값을 리턴, 같다면 그다음 문자 비교
          • 한 문자열이 다른 문자열의 접두사인 경우, 두 문자열의 길이 차이를 반환
          • 두 문자열이 동일하면 0을 반환
        • 숫자비교
          • 클경우 → 양수
          • 작을경우 → 음수
          • 같을경우 0
      • Comparator<T> 인터페이스
        • Comparable과 마찬가지로 두 객체간의 비교를 위해 사용.
        • Comparator를 구현받은 클래스에서는 compare() 메소드를 재정의하여 사용
        • 익명객체 또는 람다함수를 통해 간결히 사용가능
      • Comparable VS Comparator
        • 공통점
          • 객체를 비교하기 위해 사용
        • 차이점
          • Comparable
            • compareTo(T o) 메소드는 파라미터(매개변수)가 한 개
            • 객체의 자연적인 비교 로직만 정의. 한 클래스에는 하나의 compareTo 메서드만 존재
          • Comparator
            • compare(T o1, T o2) 메소드는 파라미터가 두 개
            • 다양한 정렬 기준을 유연하게 사용 가능
            • 예를 들어) 학생 객체를 이름으로도 정렬이 가능하고, 점수로도 다시 정렬하려는 경우에 Comparator를 사용
  • 함수형 프로그래밍
  • 스트림API
  • 메소드 참조
  • Optional객체