Java

[Java]인터페이스(Interface)

MoZZANG 2022. 3. 16. 20:22
인터페이스(Interface)란?

: 클래스가 객체의 설계도라면 인터페이스는 클래스의 설계도라 할 수 있다.

 

 

인터페이스의 성질
  • 자바는 단일상속이 원칙이나 인터페이스를 이용해서 하나의 클래스에 다중상속을 구현할 수 있다.
  • 추상클래스처럼 상속이 목적으로 상속받은 클래스는 추상메소드를 오버라이딩해야 하기 때문에 동일한 API를 사용할 수 있다.
  • 인터페이스의 맴버로는 추상메소드와 상수로만 구성된다.
  • 인터페이스의 접근지정자는 public과 default만 가질 수 있다. modifier는 가질 수 없다.
  • 인터페이스에 있는 추상메소드는 public과 abstract키워드를 생략한다.(붙여도 되긴 된다)
  • 인터페이스의 상수 또한 public static final을 생략해도 컴파일러가 자동으로 붙여준다.
  • 자식의 오버라이딩 메소드에서는 반드시 public을 붙여야한다.
  • 클래스가 인터페이스를 상속받을 때는 implements키워드를,
  • 인터페이스가 인터페이스를 상속받을 때는 extends키워드를 사용한다.
  • 인터페이스는 생성자가 없다.

 

 

우리가 직접 예제를 통해 만들어보면서 알아보자

 

▲ 인터페이스 두개를 만들었다. 인터페이스에서 상수를 정의할 때는 public static final을 생략해도 된다. 또한 인터페이스내 추상메소드를 만들 때도 public과 abstract를 생략해도 있는 것과 동일하다.

 

 

 

▲ 추상클래스도 하나 생성하자. 추상클래스 안에서 추상메소드를 생성할 때는 반드시 abstract를 붙여야 한다.

 

 

 

▲ 우리가 위에서 만든 인터페이스 MyInter1과 MyInter2를 상속받는 일반클래스를 하나 만들었다. 인터페이스 상속을 받았기 때문에 추상클래스상속을 받은 것처럼 반드시 추상메소드를 오버라이딩 해주어야 한다.

 

여기서 의문이 드는 부분이 생길 수 있는데 MyInter1과 MyInter2에서 동일한 이름의 추상메소드 omit()을 만들었다. 그렇다면 오버라이딩될 때 과연 어느 인터페이스에 있는 추상메소드가 오버라이딩 될까?

 

우리가 인터페이스를 상속할 때 콤마(,)를 사용하여 여러 인터페이스를 다중상속하는데 위에서는 MyInter2를 먼저 상속한 것을 볼 수 있다. 이때는 먼저 상속된 인터페이스의 추상메소드가 먼저 오버라이딩 되기 때문에 여기서는 MyInter2에 있는 omit()이 오버라이딩 된 것이다.

 

 

 

▲ 이번에는 인터페이스의 상속을 받는 인터페이스를 만들어보자.

클래스가 인터페이스를 상속받을 때는 implements키워드를 사용했었다. 클래스보다 상위의 개념인 인터페이스에서 상속을 받기 때문에 '시행하다'라는 뜻의 implement를 사용한 것이다.

 

하지만 같은 레벨에 있는 인터페이스들 끼리는 클래스끼리와 마찬가지로 '확장하다' 라는 의미가 있는 extends를 키워드로 사용한다.

 

 

 

▲마지막으로 추상클래스와 인터페이스를 모두 상속받는 클래스를 만들어보자. 위 코드처럼 클래스를 상속받을 때는 extends를, 인터페이스를 상속받을 때는 implements를 사용하면 된다. 추상클래스와 인터페이스에 있는 모든 추상메소드를 오버라이딩해야함을 잊지말자.

 

 

 

 

이제 메인메소드에서 호출해보자.

추상클래스와 마찬가지로 인터페이스 또한 동질화 인스턴스화가 불가능하다. 따라서 이질화 인스턴스화를 해야한다.

 

mi2.noOmit(); 이 undefined로 에러가 나는 이유는 메모리안에서 MyInter2형의 mi2안에는 noOmit()메소드가 없고, 또한 MyInter1형의 mi1에 있는 noOmit()메소드가 보이지 않기(invisible) 때문이다.

 

기본적으로 타입이 다르고 상속관계가 없으면 형변환이 불가능하지만, 인터페이스는 상속관계가 없고 타입이 달라고 형변환이 가능하다는 점이 특이하다. 하지만 실무에서는 인터페이스를 상속을 받고있는 자식클래스로 형변환을 많이 한다.

 

 

▲ 인터페이스 상수에 접근하는 방법은 클래스와 동일하다. 인터페이스명.상수 또는 상속받은 클래스명.상수를 사용하면 사용할 수 있다.

 

 

 

 

 

이처럼 인터페이스는 단일상속밖에 지원하지 않는 클래스를 넘어서 다중상속지원이 가능하기 때문에 다중상속이 필요한 경우에 사용할 수 있다.