JAVA) 인터페이스(interface) 정의, 사용 이유
인터페이스란?
클래스들이 구현해야 하는 동작을을 강제한다.
추상화클래스에서 추상메서드로 구현한것은 상속받은 클래스가 무조건 오버라이딩 해야했던 것처럼
인터페이스가 가진 모든 메서드는 구현받은 클래스가 모두 구현해야한다.
즉, 그 안의 모든 메서드를 전부 복붙해서 가져와야 한다는것이다.
인터페이스는 기능의 틀을 짜놓고 가져아서 구현하게 하는 것에 목적이 있기때문에
외부에서 잘 가져갈 수있도록 인터페이스의 멤버는 public 접근제한자만 쓴다. (default, static제외)
인터페이스는 정말 강력한 규제다.
추상화는 추상메서드만 가져오면 됐지만, 인터페이스는 모두, 하나도 남김없이 다 가져와서 구현해야한다.
그런데 자바 8부터는 강력한 규제가 완화됐다.
자바 8부터 달라진 interface
이전에는 인터페이스에 상수, 추상메서드({ }없는 메서드)만 만들 수 있었는데,
자바 8부터는 default 와 static 메서드({ }가 있는 )도 만들 수 있도록 바꼈다.
default와 static은 오버라이딩 필수가 아니며, 원래 규제가 엄청 심했던 인터페이스에 유연성이 생겼다.
public interface Car {
public String car_name = "c";
public void go();
public void stop();
default String emergency_method(int n) {
return "위험한 상황입니다";
}
static void crash_method() {
System.out.println("충돌");
}
}
static은 인스턴스 생성없이 사용하기때문에 [ 인터페이스명.메소드명(); ]으로 사용한다.
// interface static method 사용방법
Car.crash_method();
인터페이스 사용 이유
자바8버전부터 바뀐 내용을 보니.. 정말 추상화랑 다를게 하나도 없어보인다.
왜냐면 추상화는 강제 오버라이딩과 일반 메서드 다 사용가능하니까 interface가 하는일을 다 대체할 수 있다.
그럼 추상클래스만 사용하면되지 왜 인터페이스만 사용할까?
바로, 인터페이스는 다중 상속이 가능하기 때문이다.
자바는 클래스 딱 한개만 상속받을 수 있는데 인터페이스는 여러 개 구현이 가능하다.
예를 들어 아래와 같이 클래스들이 정의되어있다고 해보자.
abstract class A - a메서드 | abstract B - b메서드 | abstract C - c메서드 |
a, b, c메서드 기능이 필요한 클래스가 5개 정도 있다고 했을때,
추상클래스는 하나만 상속 가능하므로 셋 중에 하나만 상속하고 나머지 두 메서드는 직접 적어야한다.
근데 여기서 B, C가 인터페이스라면, 셋다 상속이 가능해지는 것이다.
class D extends A implements B, C { } |
이렇게 상속(extends)은 기본 틀을 잡는데에 주로 사용하고, 기능들은 interface를 구현해서 사용한다.
인터페이스 VS 추상화
추상화 | 인터페이스 | |
공통점 | - 추상화&인터페이스 매서드는 구현부(바디, { } )가 없는 메서드 형태. ex) public abstract void abstract_method(); ex) public void interface_method(); - 오버라이딩 강제성이 있다. |
|
선언부 | abstract | interface |
물려받는 키워드 | 상속 (extends) ex) class AbClass extends Aclass{ } |
구현 (implements) ex) class ImClass implements Aclass{ } |
내부 매소드 | 일반 메소드, 추상 메서드 둘다 가능 | 추상 메서드만 구현 가능 (JAVA 8부터는 default, static 가능) |
다중 상속 | 불가능 | 가능 |
관계 | is ~ a (~이다) | has ~ a (~가능한) |
다중 상속
위에서 말한 인터페이스의 다중 상속 특징이다.
class ParentClass {
public void p() { System.out.println("일반메서드"); }
}
interface A {
public void a();
}
interface B {
public void b();
}
class Test extends ParentClass implements A, B, C {
public void a() {}
public void b() {}
}
인터페이스끼리도 상속할 수 있다.
interface A {
public void a();
}
interface B extends A {
public void a();
}