static
Interface
- 클래스 또는 프로그램이 제공하는 기능을 명시적으로 선언
- 인터페이스는 추상 메서드와 상수로만 이루어져있다.
상수명은 대문자와 '_'를 사용
- static 메소드는 사용 가능하다.
하지만 static 블록은 사용 불가능하다.
interface Practice {
(final/static : 지우라고뜸) 타입 상수명(대문자 convention) = 값;
String HI = "Hi~";
List<String> findAllName();
default 타입 메소드명(파라미터,...) {...}
default void printHi() {
System.out.println(HI);
}
static void printHi() {
System.out.println(HI);
}
}
Interface vs 추상클래스 사용
추상클래스
- 여러개의 가까운 클래스들 사이에 동일한 코드를 나누어서 사용하고 싶을때.
- 추상클래스를 상속한 클래스들이 많은 공통 메소드들과 필드와 public 보다 다양한 접근 제어자에 의해 사용하고 싶을때.
- non-static 과 non-final 필드를 선언하고 싶을때. 결과적으로 객체들의 상태를 메소드에서 접근하고 수정 할 수 있게 되겠지.
인터페이스
- 크게 상관없는 클래스들이 너의 인터페이스를 구현해야 할 필요가 있을때. 예를들어 Comparable and Cloneable
- 특정 데이터타입의 행위를 특별하게 구현하길 원할때 그러나 누가 그것의 행위를 구현 했는지에 대한 관심은 없을때
- 다중 구현상속의 이점을 누려야 할때
다향성을 구현하는 기술
- 상속 또는 인터페이스의 자동 타입 변환(Promotion)
값의 허용 범위가 작은 타입이 허용 범위가 큰 타입으로 대입될 때 자동으로 타입 변환이 일어나는 것
Upcasting은 자동으로 변환되지만, Downcasting은 데이터의 손실이 있을 수 있으므로 직접 해야한다.
모든 클래스는 Object를 상속받고있으므로 Object로 Upcasting이 가능하다.
- Dynamic Dispatch 동작
런타임 시점에서 오버라이딩된 메소드에 대한 호출이 확인됨
함수형 인터페이스
- 추상메소드를 하나만 가지고있는 인터페이스
자바는 클래스 없이 메소드를 구현할 수 없기 때문에 함수형 인터페이스가 필요
@FunctionalInterface
애노테이션(@)을 인터페이스에 선언하면 컴파일 시점에 추상메소드를 하나만 가지고있는지 확인해준다.
@FunctionalInterface
public interface Sum {
int intSum(int x, int y);
}
람다 표현식(Lambda Expression)
int sum(int x, int y) {
return x + y;
}
(x, y) -> x + y;
스트림
- 배열이나 컬렉션에 담긴 데이터를 다룰 때, 반복문이나 iterator를 사용하면 코드가 길어지고, 가독성이 떨어진다. 이 문제를 해결하기 위해 Stream API가 사용된다.
- 스트림은 원본 데이터를 변경하지 않는다. -> Immutable
- 스트림은 재사용이 불가능하다.
- 스트림 파이프라인 : 0~N개의 중개 연산과 1개의 종료 연산으로 구성
- 중개 연산 : Stream을 리턴
- 종료 연산 : Stream을 리턴하지 않기 때문에 재사용이 불가능
Optional
- NPE(Null Pointer Exception) 예외를 Optional이 제공하는 메소드로 회피할 수 있다.
- Optional는 null이 올 수 있는 값을 감싸는 Wrapper 클래스로, 참조하더라도 NPE가 발생하지 않도록 도와준다.
- Optional 클래스는 아래와 같은 value에 값을 저장하기 때문에 값이 null이더라도 바로 NPE가 발생하지 않으며, 클래스이기 때문에 각종 메소드를 제공해준다.
- Optional은 메소드 반환 타입으로만 제한적으로 사용해야 한다.