인터페이스, 인터페이스... 어디서 들어본 단어 같다. GUI 그래픽 유저 인터페이스, UI 유저 인터페이스 그런 용어를 들어본 것 같다.

 

일단 인터페이스라는 단어의 뜻을 살펴보자.

 

*dictionary.com 의 정의

 

- a surface regarded as the common boundary of two bodies, spaces, or phases.

>> 두 몸체, 공간, 위상의 공통의 경계라고 여겨지는 표면

 

- the facts, problems, considerations, theories, practices, etc., shared by two or more disciplines, procedures, or fields of study

>> 두개 이상의 원리,절차,분야에 대한 학문이 공유하는 사실,문제,고찰,이론,실행 등

 

- 종합하면 Interface는 두개의 대상이 맞닿는 부분, 접하는 부분에 대한 것이라는 것을 알 수 있다.

 

흔히 게임의 UI 유저 인터페이스라고 하면 게임이 시작되면 유저와 상호작용하면서 진행이 된다. 그 접하는 부분이 화면에 표시되는 그래픽이건 사운드이건 사람이 예상하여 조작할 수 있는 범위가 된다. 조작감이 안좋거나 그래픽 전달력이 약해서 내맘데로 진행이 안되면 인터페이스가 불편하다고 한다. 인간과 컴퓨터의 인터페이스는 광범위하다. 길거리의 광고판일수도 있고, 도로의 표지판일 수도 있다. 대상들이 서로 접해서 상호작용이 일어나는 것이다.

 

자바의 인터페이스는 객체와 객체간 관계에서 바라볼 필요가 있다. 인터페이스는 추상 클래스처럼 구현할 수 없다. 그러면 추상클래스만 있으면 되지 왜 인터페이스까지 나와서 더 복잡하게 하느냐? 라는 문제가 있을 수 있다. 결론은 둘다 필요하기 때문이다. 자바의 다형성을 만들기 위해서 추상클래스와 인터페이스 둘의 믹스가 필요하다.

 

1) 인터페이스 예제 (interface)

public interface InterfaceEX {
	
	// final variables
	int daysYear = 365; // 1년
	int monthsYear = 12;
	
	void InterPtype1(int iNum1);
	void InterPtype2(double dNum1);
	void InterPtype3(String str1);
}

인터페이스를 만드는 예제를 보여준다. 클래스 같이 보이는데 뭔가 다르다.

 

>> 멤버변수는 실제 상수이다. 컴파일러가 자동으로 final 을 붙인다. 초기화를 시키지 않는다면 컴파일 오류가 난다. 인터페이스는 일반 멤버 변수를 가질 수 없다.

 

>> 인터페이스의 메소드는 구현코드가 없다. 따라서 { } 이 아니라 ; 로 끝난다. 추상클래스에서도 코드를 구현하지 않을 경우 ; 세미콜론으로 메소드의 선언을 끝맺음했다. 예제에는 세개의 메소드가 있다. 다음 하위 클래스에서는 이 세개를 구현해야 일반 클래스가 된다. 한 개라도 인터페이스를 구현하지 않는다면 컴파일 되지 않는다. 인터페이스의 추상메소드에는 abstract 도 붙이지 않는다. 컴파일러가 자동으로 처리한다.

 

하위 클래스에서 인터페이스를 상속한다. 클래스는 extends 키워드였다. 인터페이스는 implements 키워드를 사용한다. 오류메시지를 보니 인터페이스는 반드시 must 상속받은 추상 메소드를 구현해야 한다. 메소드를 재정의 Override 해준다. 마지막 줄에 하위 클래스 고유의 메소드도 정의한다.

 

>> 만약 추상메소드 중에 한개라도 정의하지 않는다면 그 클래스는 추상클래스가 된다.

 

>> 클래스는 단일 상속이지만 인터페이스의 구현은 1개 이상 할 수 있다. 즉 다중상속이 가능하다.

public class InterfaceTest implements InterfaceEX{

	@Override
	public void InterPtype1(int iNum1) {
		System.out.println(iNum1);
	}

	@Override
	public void InterPtype2(double dNum1) {
		System.out.println(dNum1);
	}

	@Override
	public void InterPtype3(String str1) {
		System.out.println(str1);
	}
    public void showMInfo() {
		System.out.println("InterfaceEx를 구현한다");
	}
}

*테스트를 한다.

	public static void main(String[] args) {
		InterfaceTest it1 = new InterfaceTest();
		it1.InterPtype1(10);
		it1.InterPtype2(5.5);
		it1.InterPtype3("String test");
		it1.showMInfo();
	}

결과값

추상클래스의 코드를 다 구현하고 나서 클래스의 인스턴스를 생성할 수 있다.

 

*형변환(class type conversion)

	public static void main(String[] args) {
		InterfaceEX it1 = new InterfaceTest();
		it1.InterPtype1(10);
		it1.InterPtype2(5.5);
		it1.InterPtype3("String test");
		// it1.showMInfo(); 하위클래스 코드이므로 형변환 된 클래스 참조로 사용이 안된다.
	}

클래스와 같다. 인터페이스를 상속했으므로 하위클래스 인스턴스를 생성하면서 상위 클래스인 인터페이스의 형으로 묵시적 변환이 가능하다. 이때 하위클래스에만 있는 showMInfo( ) 메소드는 사용이 불가능하다.

 

*인터페이스의 상수(final, constant)

public interface InterfaceEX {
	
	// final variables
	int daysYear = 365; // 1년
	int monthsYear = 12;
	
	void InterPtype1(int iNum1);
	void InterPtype2(double dNum1);
	void InterPtype3(String str1);
}

처음의 예제를 다시 보자. 인터페이스에는 상수만 있다고 했다. 인터페이스는 인스턴스를 생성할 수 없고 멤버 변수도 사용할 수 없다. 멤버 변수처럼 선언한 것은 상수이다. 컴파일러가 자동으로 final을 붙인다. 명시적으로 final을 사용해도 무관하다.

 

*디폴트 메소드 (default method)

아래 메소드를 인터페이스에 추가한다. 인터페이스의 메소드는 구현을 안한다고 말했다. 자바8부터는 default 키워드를 사용하여 인터페이스의 실제 구현코드를 추가할 수 있다. 물론 인터페이스의 인스턴스를 생성할 수 있다는 것은 아니다.

	default void InterfaceShowInfo() {
		System.out.println("인터페이스의 default 구현");
	}

*실행은 인터페이스를 implements 한 클래스에서 구현한다. default 로 메소드가 구현되어 있기 때문에 사용전에 오버라이드 할 필요는 없다. 만약 인터페이스의 default 메소드가 하위클래스의 기능과 맞지 않는다면 오버라이드를 통해 재정의 할 수 있다.

 

규칙은 클래스를 인스턴스로 만들기 전에 추상클래스가 하나라도 남아있으면 안되는 것이다.

 

*정적 메소드 (static method)

 

클래스 메소드에서 나왔던 정적 메소드이다. 인터페이스의 메소드를 추가한다. static 키워드를 붙인다.

	static void iTest() {
		System.out.println("static test");
	}
		InterfaceEX.iTest();

클래스변수와 같다. 인스턴스를 생성하지 않고 인터페이스의 이름을 . 도트연산자로 직접 사용할 수 있다.

 

*private 메소드

private 메소드는 인터페이스 안에서만 접근이 가능하다. 하위클래스에 구현해도 나오지 않으므로(is not visible) 인터페이스 내부에서 default나 static 메소드에서 사용이 가능하다. 

 

자바9 부터 바뀐 내용이니 그전까지의 자바에서는 사용하지 않는다는 점도 유의할 필요가 있다. 많은 국내 학습교재들은 자바8을 기준으로 예제 코드가 작성되어 있다.

	private static void iTest() {
		System.out.println("static test");
	}
	
	default void InterfaceShowInfo() {
		System.out.println("인터페이스의 default 구현");
		iTest();
	}

 

다소 반복적인 내용일 수도 있고 똑같은 말을 다른 말로 하기도 하고 헷갈릴 수도 있다. 그래서 객체지향 프로그래밍이 익숙해질려면 시간이 걸리는 것이니, 자신만의 클래스를 직접 개발해보고 프레임워크도 사용하다 보면 익숙해질 것이다. 유명 자바 강사들도 인터페이스는 한번에 이해하기가 어렵다고 하니 너무 조급함을 가질 필요가 없다.

공유하기

facebook twitter kakaoTalk kakaostory naver band