인터페이스(interface)
인터페이스의 구현
- 상속이라는 뜻과 동일
- '클래스가 인터페이스를 구현한다.' 라고 말한다.
- extends 키워드대신 implements(구현) 키워드를 사용하며, 인터페이스를 구현한다고 한다.
class AA implements A{} -> 클래스 AA는 인터페이스 A를 구현하는 클래스라는 뜻.
- implements는 다중으로 사용할 수 있다.
인터페이스 사용
인터페이스를 이용한 다형성
class AA{
void tmp(BB bb){
bb.tmp();
}
}
class BB{
void tmp(){
System.out.println("BB");
}
}
class CC{
void tmp(){
System.out.println("CC");
}
}
public class Main{
public static void main(String[] args){
AA a = new AA();
a.tmp(new BB());
}
}
- 위와같이 코드를 짜면 A가 B에 강하게 의존(Dependency)하고 있다.
B가 변경되면 A가 에러가 난다.
- B대신 C를 A에서 사용하고 싶으면 A클래스의 tmp메서드의 인자(매개변수)도 C로 바꿔줘야 한다.
interface I{
public abstract void tmp();
}
class AA{
void tmp(I i){
bb.tmp();
}
}
class BB implements I{
void tmp(){
System.out.println("BB");
}
}
class CC implements I{
void tmp(){
System.out.println("CC");
}
}
public class Main{
public static void main(String[] args){
AA a = new AA();
a.tmp(new BB());
}
}
- 기존방식은 A클래스에 무조건 한 종류의 클래스만 인자로 받았어야 하는데, 그러면 수정할 때마다 인자의 타입을 바꿔주고, 보내는 main의 매개변수도 바꿔줘야 한다. (일일히 다 신경써야 한다. )
- 그래서 인터페이스를 선언부만 만들고, 그 인터페이스를 이용해서 B나 C를 구현하면 (다형성 개념) A메서드에서 인터페이스를 인자로 받게 해놓고, main에서는 인터페이스를 구현한 자식클래스 (B, C)를 매개변수로 보내면 A를 별도로 수정할 필요가 없다.
- BB나 CC는 인터페이스를 구현했기 때문에 AA의 tmp()에 보낼 수 있다.
DI (Dependency Injection)
- 느슨한 결합
- 의존성을 낮추기 위함.
- 중간다리를 놔서 에러가 나도 중간다리만 에러가 나게 한다.
class AA{
void tmp(){
BB bb = new BB();
bb.tmp();
}
}
class BB{
void tmp(){
System.out.println("BB");
}
}
public class Main{
public static void main(String[] args){
AA a = new AA();
a.tmp();
}
}
- 위와같이 A에서 직접 B를 불러서 사용하면 Injection이 아니다.
이렇게 하면 B를 직접 불러서 쓸 때 오류가 나면 A에서 바로 터진다.
class AA{
void tmp(BB bb){
bb.tmp();
}
}
class BB{
void tmp(){
System.out.println("BB");
}
}
class CC{
void tmp(){
System.out.println("CC");
}
}
public class Main{
public static void main(String[] args){
AA a = new AA();
a.tmp(new BB());
}
}
- 위와같이 Main이라는 중간다리에서 B를 생성해서 A에게 보내고 A에서 실행을 하게 되면 만약 터져도 A가 터지지 않고 Main이 터지게 된다.
- 이렇게 의존성을 조금 줄여서 사용하는 것이 좋다.