
인터페이스는 interface 키워드를 통해 선언할 수 있으며 implements 키워드를 통해 일반 클래스에서 인터페이스를 구현할 수 있다.
또한, JAVA8 이전까지는 상수, 추상메소드만 선언이 가능하지만,
(상수, 추상메소드만 가능케했다는 것을 통해 그만큼 강제성이 강했다는 것을 유추할 수 있다.)
JAVA8부터 디폴트메소드, 정적메소드가 추가되었다.
(디폴트메소드, 정적메소드를 통해, 구현 강제성 안에 유연함을 심었다고 우선 이해하자)
public interface 인터페이스명 {
타입 상수명 = 값;
(final/static : 지우라고뜸) 타입 상수명(대문자 convention) = 값;
String HI = "Hi~";
타입 메소드명(매개변수, ... );
List<String> findAllName();
-추상메소드를 오버라이드하지않으면 빨간줄이 뜸 -> 추상메소드로 구현체에게 구현 강제
default 타입 메소드명(매개변수, ... ){
//구현부
default 타입 메소드명(파라미터,...) {...}
default void printHi() {
System.out.println(HI);
}
public . 생략시 컴파일 과정에서 붙음.static 타입 메소드명(매개변수) {
//구현부
static void printHi() {
System.out.println(HI);
}
}
참고 : https://limkydev.tistory.com/197
promotion memory구조 보기

extends Object 가 생략되어있다. ->모든클래스는 오브젝트를 상속하고 있기 때문!! 알고있어야함.인터페이스는 생성자가 없다.
clazz: 클래스 대신에 작성하는 팁 / Object anyClazz = new AnyThing();
public class ACar {
public void print() {
System.out.println("A");
}
}
public class BCar extends ACar { //메소드 오버라이딩 - ACar상속 후 함수 재정의
public void print() {
System.out.println("BCar");
}
}
//ex) 스태틱 메서드 디스패치
public static void main(String[] args) {
BCar bcar = new BCar();
System.out.println(bcar.print()); //BCar를 출력.
}
public interface Car {
void print();
}
public class A implements Car {
@Override
public void print() {
System.out.println("A");
}
}
public class B implements Car {
@Override
public void print() {
System.out.println("B");
}
}
// 예시 1
public static void main(String[] args) {
// 다이나믹 메소드 디스패치
Car car = new A();
System.out.println(animal.print());
}
런타임 전에는 객체 생성이 되지 않기 때문에 Car car = new A();를 해도, 컴파일러는 A가 생성됨을 알 수 없으므로 Car가 정의한 print() 메소드만 접근 가능.
참고 : https://doompok.tistory.com/21
자바는 Promotion으로 Upcasting된 객체의 메소드를
런타임 시점에서 오버라이딩된 메소드에 대한 호출이 확인된다. → Dynamic Method Dispatch -> 실시간 다형성

오버라이딩(Overriding)
상위 클래스의 메서드와 이름과 용례(signature)가 같은 함수를 하위 클래스에 재정의하는 것을 말한다
즉, 상속 관계에 있는 클래스 간에 같은 이름의 메서드를 정의하는 것을 말한다.public abstract class Shape { public void printMe() { System.out.println("Shape"); } public abstract double computeArea(); } public class Circle extends Shape { private double rad = 5; @Override // 개발자의 실수를 방지하기 위해 @Override(annotation) 쓰는 것을 권장 public void printMe() { System.out.println("Circle"); } public double computeArea() { return rad * rad * 3.15; } } public class Ambiguous extends Shape { private double area = 10; public double computeArea() { return area; } } https://gmlwjd9405.github.io/2018/08/09/java-overloading-vs-overriding.htmlCircle에서 printMe() 메서드를 재정의한다.
오버라이딩을 할 때 개발자의 실수를 방지하기 위해 메서드 위에 @Override 를 관례적으로 적는다.
참고 : https://gmlwjd9405.github.io/2018/08/09/java-overloading-vs-overriding.html
함수형 인터페이스
추상 메소드를 하나만 가지고 있는 인터페이스
자바는 클래스없이 메소드를 구현할 수 없기 때문에 이런 함수형 인터페이스라는 개념을 도입해서 함수를 쉽게 사용할 수 있게 함.
@FuntionalInterface 에노테이션을 선언하면 컴파일 시점에서 추상메소드를 하나만 갖는지 체크해줌.
-> 컴파일 시 추상메소드가 하나일 수 있도록 강제해줌.
@FunctionalInterface
public interface Sum {
int intSum(int x, int y);
}
에노테이션 : 인터페이스 위에 골뱅이 붙은 애들 ex) @FuntionalInterface
➕ 익명 객체란?
프로그램에서 일시적으로 한번만 사용되고 버려지는 객체
-나중에 다시 불러질 이유가 없다는 뜻
사용 이유 : 1. 프로그램 내에서 일시적으로(단발성으로) 한번만 사용되어야 하는 객체일 경우
-> UI 이벤트처리, 스레드 객체 등 (단발성 이벤트 처리)
2. 재사용성이 없고, 확장성을 활용하는 것이 유지보수에서 더 불리할 때
-> 비즈니스 로직이 정말 재각각이며, 재사용성이 전혀없어 매번 클래스를 생성해야하는 비용이 더 많을때
참고 : https://limkydev.tistory.com/226
int sum(int x, int y) {
return x + y;
}
-> 람다 표현식으로 바꾼다면
(x, y) -> x + y;
-> 람다는 리턴이 없어도 리턴이 됨
Deprecated : 더이상 지원되지 않는다.
아래 코드에서 인텔리제이가 추천해주는 코드로 변경하는 것
@FunctionalInterface
public interface Sum {
int intSum(int x, int y);
}
...
import ...Sum;
public class Main {
Sum sum = (a, b) -> a + b;
System.out.println(sum.intSum(1, 2));
}
를
...
import ...Sum;
public class Main {
Sum sum = Integer::sum;
System.out.println(sum.intSum(1, 2));
}
로 바꾸라고 추천해줌 ( (a, b) -> a + b; -> Integer::sum;)
해결책 : Stream API
스트림 파이프라인 : 0~N개의 중개 연산과 1개의 종료 연산으로 구성
파이프라인 : 인련의 과정, 순서, 작업 순서가 중요
filter , distinctmap , flatMaplimit , skipsortedforEachfindFirst, findAnycount, min, maxsum, averagecollect옵셔널 등장 배경 : 메소드에서 리턴을 널처리 하지않고 널포인트 익셉션이 발생하지 않도록 노력한 자바 아키텍쳐들의 노력의 결과물
Wrapper Class : 기본 자료타입(primitive type)을 객체로 다루기 위해서 사용하는 클래스들을 래퍼 클래스(wrapper class)라고 합니다.
참고 : https://coding-factory.tistory.com/547
Optional<String> opt = Optional.ofNullable("Optional은 Wrapper Class");
System.out.println(opt.get());
⚠️ 잘못 사용하면 오히려 코드가 오히려 지저분해지고, 의미 없는 동작, Side-Effect 유발이 많이 발생할 수 있음.
리스트의 경우 for문을 사용해서 어떤 값을 뽑아내고 그 값을 변수를 하나 설정해서 add해주고 그 값을 뽑아내서-??
값스트림을 쓰는 이유
: 병렬처리가 가능함 / 병렬처리 : 여러가지 일을 한 번에 수행하는 것
: 유지보수가 쉽다.
문자열 붙이는 방법:
-String : 문자열 연산이 적고 멀티쓰레드 환경일 경우
-StringBuffer : 문자열 연산이 많고 멀티쓰레드 환경일 경우
-StringBuilder : 문자열 연산이 많고 단일쓰레드이거나 동기화를 고려하지 않아도 되는 경우 -> 연산이 적은 경우 적은 데이터만 가지고 쓰니까 빨라짐 시간복잡도 내려감
그렇다면 동일한 API를 가지고 있는 StringBuffer, StringBuilder의 차이점은 무엇일까요?
- 가장 큰 차이점은 동기화의 유무로써 StringBuffer는 동기화 키워드를 지원하여 멀티쓰레드 환경에서 안전하다는 점(thread-safe) 입니다. 참고로 String도 불변성을 가지기때문에 마찬가지로 멀티쓰레드 환경에서의 안정성(thread-safe)을 가지고 있습니다.
포함관계 : Ex) reservation.userPhone '.'으로
파일경로처럼 불러오기
메인 내부에서 다 끝나면 종료시키는 것.
sys.exit(0); : 정상종료
sys.exit(1); : 강제종료
클래스간의 포함관계

Circle circle = new Circle(); → circle.(Point)c.x or circle.(Point)c.y
포함관계 : ‘~은~을 가지고 있다.(has-a)’
상속관계 : ‘~은~을 이다.(is-a)’ extends

원(Circle)은 점(Point)이다. - Circle is a point.
원(Circle)은 점(Point)을 가지고있다. - Circle has a Point.
90%이상이 포함 관계이다.! 상속은 제약이 있어 꼭 필요 할 때만.
잘 모르면 포함으로 진행해라. 대부분 포함이다.