[Java] 자바 인터페이스 (interface)의 기본 문법과 꼭 지켜야 하는 규칙


인터페이스(interface)의 내부 규칙 I

 - 인터페이스는 호출 규칙을 정의하는 것이기 때문에 추상 메서드만 선언 가능하다.

 - 인터페이스는 인스턴스 변수를 가질 수 없다.

   즉 인터페이스에 선언된 모든 메서드는 public이고 abstract이다.

   또한 인터페이스에 선언된 모든 필드(영역)는 public이고 static이며 final이다.



인터페이스(interface) 예제 

public interface A {
  // 1) 규칙이기 때문에 무조건 공개 메서드이고 추상 메서드이다.
  public abstract void m1();
 
  // 2) public을 생략해도 내부적으로 public으로 간주한다.
  abstract void m2();
 
  // 3) abstract를 생략해도 내부적으로 abstract로 간주한다.
  void m3();
 
  // 4) 절대 구현 메서드를 가질 수 없다.
  // void m4() {} // 컴파일 오류!

  // [필드 선언 규칙]
  // 1) 규칙이기 때문에 무조건 공개 필드이고, 스태틱 필드이다
  //    그리고 값을 바꿀 수 없는 상수 필드이다.
 
  public static final int v1 = 200;
 
  // 2) public을 생략하면 내부적으로 public으로 간주한다.
  static final int v2 = 200;
 
  // 3) static을 새약하면 내부적으로 static으로 간주한다.
  final int v3 = 200;
 
  // 4) final을 생략하면 내부적으로 final로 간주한다.
  int v4 = 200;

}





인터페이스(interface)의 규칙 II

 - 인터페이스도 상속 받아 서브 인터페이스를 만들 수 있다.



A 인터페이스로부터 상속 받은 B 인터페이스의 예제


public interface B extends A {

  /*public static final*/ int v5 = 300;
  /*public abstract */ void m4();
}

public interface C extends A {
  /*public static final*/ int v6 = 300;
  /*public abstract */ void m5();
  /*public abstract */ void m6();
}




인터페이스(interface)의 규칙 III

 - 인터페이스는 다중 상속이 가능하다.

 - 어차피 구현되지 않은 메서드이기 때문이다.



B 인터페이스와 C 인터페이스로부터 다중 상속 받은 D 인터페이스 예제

public interface D extends B, C {
  // 어차피 인터페이스의 모든 메서드는 구현된 게 아니기 때문에,
  // 서브 인터페이스에서 수퍼 인터페이스의 메서드를 다시 선언하더라도 문제는 없다.
  // => 다만 부질 없는 짓이다.
  // void m3();
 
  // 다음과 같이 메서드를 추가하는 것은 안된다.
  // 이미 같은 이름을 가지고 파라미터의 타입도 일치하는 메서드가 있는데
  // 리턴 타입만 달리해서 메서드를 선언하면
  // 나중에 크래스에서 이 메서드를 구현할 때 구분할 수 없기 때문에 이것은 불가능하다.
  // int m3(); // 컴파일 오류!
 
  // 파라미터가 다르다면 오버로딩이 가능하기 때문에 괜찮다.
  void m3(int a);
 
  // 파라미터만 다르다면 당연히 오버로딩이 가능하기 때문에 괜찮다.
  int m3(int a, int b);
 
  // B에도 m5()가 있고, C에도 m5()가 있다.
  // 그러나 어차피 구현한 메서드가 아니기 때문에 둘 중 어느 것을 가져와도 된다.
  // 그래서 인터페이스는 다중 상속을 허락한다.
 
  void m7();

}



정리!


B, C 인터페이스의 추상 메서드를 재정의 하는 MyClass 클래스 예제


public class MyClass implements B, C{

  // B와 C의 수퍼 인터페이스는 A의 메서드 구현
  public void m1() {}
  public void m2() {}
  public void m3() {}
 
  // B에 선언된 메서드 구현
  public void m4() {}
  public void m5() {}
 
  // C에 선언된 메서드 구현
  // public void m5() {} // 이미 위에서 m5()를 구현했기 때문에 다시 구현할 필요는 없다.
  public void m6() {}

}



*주의!

- 만약 'E'라는 새로운 인터페이스에서 int m5()를 선언했을 경우,

  MyClass가 E를 상속 받는다면 m5()는 리턴 타입이 다르기 

  때문에 public void m5()로는 B, C, E의 규칙을 충족시킬 수

  없다. 이 경우 컴파일 오류가 발생한다.

- 즉, 인터페이스의 메서드 리턴 타입은 모두 동일해야 한다.






블로그 이미지

필로그래머

,