
Inter+face
말 그대로 얼굴 사이에 위치한 것이다. 인터페이스도 일종의 추상 클래스? 라고 생각할 수 있지만 많은 부분이 다르다.
public interface NAME{
public static final TYPE NAME1;
public static final TYPE NAME2=어쩌구;
//public static final 생략 가능
public abstract type NAME();
//public abstract생략가능
}
기본적으로 class를 사용하지 않고 interface 키워드를 사용한다. 필드에는 기본적으로 public static가 사용되며, 메소드는 기본적으로 public abstract가 사용된다.
인터페이스는 static, default 메소드를 이용해서 어느정도 구현이 가능하지만 기본적으로 추상 메소드를 사용하기 때문에 인터페이스를 구현하는 클래스가 필요하다
public class 클래스명 implements 인터페이스명 {
// 추상 메서드 오버라이딩
@Override
public 리턴타입 메서드이름(매개변수, ...) {
// 실행문
}
}
클래스들은 extends를 이용해서 확장하듯 상속했지만 인터페이스는 본인의 인터페이스를 구현하는 것에 초점을 맞춘다.
구현 클래스와 같이 인터페이스를 구현하는 클래스는 모든 추상 메소드를 구현해야한다. 하지만 일부만 구현하고자 하면 중간에 추상 클래스를 한번 거치면 된다.
public interface Animal {
void eat();
void sleep();
void makeSound();
}
public abstract class AnimalBase implements Animal {
@Override
public void eat() {
System.out.println("Animal is eating.");
}
@Override
public void sleep() {
System.out.println("Animal is sleeping.");
}
// makeSound()는 구현하지 않음
}
//추상 클래스는 직접 인스턴스를 만들 수 없다.
public class Cat extends AnimalBase {
@Override
public void makeSound() {
System.out.println("Cat meows.");
}
}
//Cat은 인터페이스인 Animal을 구현한 추상 클래스 AnimalBase를 구현한 클래스가 되었다.
//Cat클래스는 사실상 makeSound만 구현했지만 실상은 전부 구현한 클래스인것.
인터페이스간 상속도 가능하다. 이때는 그냥 extends 사용하면 된다.
심지어 다중 상속도 지원한다.
public class Main implements C {
@Override
public void a() {
System.out.println("A");
}
@Override
public void b() {
System.out.println("B");
}
}
interface A {
void a();
}
interface B {
void b();
}
interface C extends A, B { }
추상 클래스나 인터페이스 모두 구현 메소드를 가질 수 있다.
interface A {
void a();
default void aa() {
System.out.println("AA");
}
}
이렇게 default 키워드를 사용하면 구현이 가능하고,
static키워드를 사용하면 다음과 같다.
public class Main implements A {
@Override
public void a() {
System.out.println("A");
}
public static void main(String[] args) {
Main main = new Main();
main.a();
main.aa();
System.out.println();
// static 메서드 aaa() 호출
A.aaa();
}
}
interface A {
void a();
default void aa() {
System.out.println("AA");
}
static void aaa() {
System.out.println("static method");
}
}
A 구현체 Main이 있음에도 불구하고 A.aaa()를 통해 인터페이스 명으로 메소드를 호출 할 수 있다.