안녕하세요, 여행벌입니다.

오늘은 자바의 인터페이스(interface) 가 무엇인지, 문법 구조가 어떻게 되는지, 언제 사용하는지 알아보겠습니다.


인터페이스(interface)

 인터페이스의 사전적 의미는 "연결점" 또는 "접점"으로

자바에서는 둘 사이를 연결하는 매개체의 역할을 합니다.

인터페이스(interface) 기본 문법

 인터페이스는 문법적인 면에서 클래스와 굉장히 비슷합니다.

interface 인터페이스이름{
	// 변수들
	// 메소드들
}

 class 대신 interface 선언이 붙어있고, 마찬가지로 안에는 각종 변수와 메소드가 존재합니다. 하지만, 기본적으로 메소드는 몸체가 비어 있는 "추상 메소드" 입니다.  아래와 같이 몸체가 비어 있는 메소드를 추상 메소드라고 합니다.

public void example(int a);

 그럼 인터페이스의 메소드는 몸체가 비어 있는데 어떤 기능을 할까요?? 클래스에서 인터페이스를 '상속' 이 아닌 "구현"을 하고, 이때 비어있는 메소드인 "추상 메소드" 를 클래스에서 구현해서 사용합니다. 즉, 저번 포스팅에서 다룬 오버라이딩을 통해 추상 메소드를 이용할 수 있습니다.

 

인터페이스에는 다음과 같은 특징이 있습니다.

 

● 인터페이스는 인스턴스 생성이 불가능하다.

● 인터페이스형을 대상으로 참조 변수 선언은 가능하다.

● 인터페이스는 클래스가 "상속" 하는게 아닌 "구현"을 하고 implements 키워드를 사용한다.

● 한 클래스가 둘 이상의 인터페이스를 동시에 구현할 수 있다.

● 추상메소드와 이를 구현하는 메소드 사이에 오버라이딩이 성립하고, @Override 어노테이션을 사용할 수 있다.

● 인터페이스 안에 있는 모든 "추상 메소드"를 구현하지 않으면, 해당 클래스를 대상으로 인스턴스 생성은 불가능하다.

 

 그럼 간단한 예시를 통해서 인터페이스의 특징을 살펴보겠습니다.

package Hello;

interface print{
	public void print(String name);
}

class printName implements print{
	@Override
	public void print(String name) {
		System.out.println(name + "님 환영합니다.");
	}
}

public class test{
	public static void main(String args[]) {
		printName ex1 = new printName();
		ex1.print("travelbeeee");
		
		print ex2 = new printName();
		ex2.print("travelbeeee2");
		
	}
}
[Output]
travelbeeee님 환영합니다.
travelbeeee2님 환영합니다.

 printName 이라는 클래스에서 print 인터페이스를 구현해, 추상 메소드를 사용하는 모습을 볼 수 있습니다. 또, 인터페이스 형을 대상으로 참조 변수 선언을 하고 메소드를 이용하는 모습도 볼 수 있습니다.

인터페이스 변수

 인터페이스 안에도 변수를 선언할 수 있습니다. 클래스와는 다르게 변수는 다음과 같은 특징을 가집니다.

 

● 선언과 동시에 값을 초기화 해야 한다.

● 모든 변수는 public, static, final 이 선언된 것으로 간주한다. 즉, 고정된 값 "상수" 가 된다.

 

 인터페이스 변수는 "상수"로 선언되므로, 인터페이스 변수명은 관례적으로 대문자로 짓습니다.

interface print{
	string INTERFACE_NAME = "print_Interface";
	int INTERFACE_AGE = 9999;
	public void print(String name);
}

인터페이스 메소드

 인터페이스 안에는 "추상 메소드" / "디폴트(default) 메소드" / "클래스(static) 메소드" 를 선언할 수 있습니다.

 추상 메소드는 위에서 다뤘듯이 몸체가 비어 있는 메소드를 의미하고, 추상 메소드는 기본적으로 public이 선언된 것으로 간주합니다. 추상 메소드는 인터페이스를 구현하는 클래스 내에서 오버라이딩을 통해 전부 구현해줘야하고, 구현하지 않은 추상 메소드가 존재하면 안됩니다.

 

 디폴트 메소드는 자바8에서 처음 소개된 기능입니다. 추상 메소드와 다르게 자체로 완전한 메소드이고, 이를 구현하는 클래스가 오버라이딩 하지 않아도 됩니다. 이미 기존에 구현한 인터페이스에 메소드를 추가해야되는 경우에 디폴트 메소드를 이용하면, 이를 구현하고 있는 모든 클래스들에게 영향을 주지 않고 메소드를 추가할 수 있습니다.

 

 클래스 메소드도 자바8에서 처음 소개된 기능입니다. 클래스에 정의하는 static 메소드와 유사하게, 자체로 완전한 메소드이고 따로 구현하지 않아도 되고, 클래스의 static 메소드 호출 방법과 동일합니다.

package Hello;

interface print{
	public void print1( ); // 추상메소드
	default void print2() { // 디폴트메소드
		System.out.println("디폴트메소드입니다.");
	}
	public static void print3() { // 클래스 메소드
		System.out.println("클래스메소드입니다.");
	}
}

class printName implements print{
	@Override
	public void print1() {
		System.out.println("추상메소드입니다.");
	}
}

public class test{
	public static void main(String args[]) {
		print.print3();
		printName ex1 = new printName();
		ex1.print1();
		ex1.print2();
	}
}
[Output]
클래스메소드입니다.
추상메소드입니다.
디폴트메소드입니다.

 클래스 메소드는 인스턴스 생성 없이도 사용이 가능하고, 디폴트 메소드는 클래스 내에서 따로 구현하지 않고 사용하는 것을 볼 수 있습니다.

인터페이스 상속

 인터페이스도 클래스처럼 서로 상속이 가능합니다. extends 키워드를 사용해야하고, 클래스의 상속과 동일하게 작동합니다.

interface print{
	public void print1( ); // 추상메소드
	default void print2() { // 디폴트메소드
		System.out.println("디폴트메소드입니다.");
	}
	public static void print3() { // 클래스 메소드
		System.out.println("클래스메소드입니다.");
	}
}

interface colorPrint extends print{
	public void colorPrint1();
	default void colorPrint2() {
		System.out.println("칼라프린트의 디폴트메소드");
	}
	public static void colorPrint3() {
		System.out.println("칼라프린트의 클래스메소드");
	}
}

class printName implements colorPrint{
	@Override
	public void print1() {
		System.out.println("추상메소드입니다.");
	}
	@Override
	public void colorPrint1() {
		System.out.println("칼라프린트의 추상메소드");
	}
}

 마찬가지로 추상 메소드는 클래스에서 모두 구현해줘야합니다.


인터페이스를 사용하면 서로 다른 클래스에게 접점을 만들어 줄 수 있습니다.

다르지만 공통된 기능이 필요한 경우에 인터페이스를 만들고,

클래스마다 구현해 사용한다면 훨씬 효율적으로 코드를 구현할 수 있습니다.

이처럼, 인터페이스는 자바에서 많은 역할을 해줍니다.

 

 

 

 

+ Recent posts