인터페이스

고재석·2021년 3월 17일
0

Java는 기본!

목록 보기
5/12

인터페이스란?

인터페이스란 다양한 클래스의 공통 기능을 미리 정리해놓은 기능 설계도라고 볼 수 있다.

따라서 객체를 사용하는 개발자 입장에서는 이 객체가 구현하는 인터페이스만 보더라도 이 객체의 사용방법을 이해할 수 있다. 그리고 다형성의 측면에서도 개발자가 이 인터페이스의 메소드를 호출하게 된다면 구현 객체의 메소드가 실행된다.

직접 구현 객체의 메소드를 호출할 수도 있지만, 이렇게 구현하는 경우에는 각 객체를 모두 다 생성해서 사용해야한다. 하지만 인터페이스를 사용한다면 인터페이스는 하나만 생성하고 거기에 구현 객체를 만들어서 사용하고 반납하면 된다.


인터페이스의 구성 요소

상수 필드

인터페이스는 인스턴스가 아니기 때문에 일반 필드는 선언할 수 없다. 하지만 상수 필드는 선언해서 어떤 인스턴스든 가져다 사용할 수 있도록 할 수 있다.

추상 메소드

인터페이스는 추상 클래스와 마찬가지로 추상 메소드를 가질 수 있다. 보통 모든 메소드를 추상 메소드로 선언해서 인터페이스를 구현하는 객체들에게 메소드 구현을 강제하고 이를 통해 객체의 기능 설계도로써의 역할을 수행한다.

디폴트 메소드

디폴트 메소드는 인터페이스에 선언되지만 각 구현 객체의 인스턴스에서 가지고 있는 메소드라고 볼 수 있다. 추상 클래스의 일반 메소드(추상 메소드가 아닌)라고 볼 수 있다.

이 디폴트 메소드는 유지보수 측면에서 큰 편리함을 준다. 예를 들어 어떤 인터페이스를 구현하는 클래스가 100개 있다고 생각해보자. 그런데 이 인터페이스에 새로운 메소드가 하나 추가되어야 한다. 그렇다면 인터페이스에 추상 메소드가 하나 추가되고 100개의 클래스에 추상 메소드에 대한 구현 메소드가 각 1개씩 총 100개가 추가되어야 한다.

이런 경우에 디폴트 메소드를 사용한다면 인터페이스에 디폴트 메소드로 구현한다면 인터페이스에서의 1번의 구현으로 100개의 클래스에 같은 메소드를 구현할 수 있다.

정적 메소드

정적 메소드는 인터페이스에 선언되어 인터페이스 자체로 사용가능한 메소드이다. 상속 개념에서 부모클래스에 static 메소드를 선언한 것과 비슷하게 사용할 수 있다.


익명 구현 객체

보통 인터페이스를 선언하고 이를 구현하는 클래스를 따로 만들어서 개발하게 된다. 하지만 임시 작업 스레드를 만들기 위해서 익명 구현 객체를 활용하는 경우가 많이 발생한다.

Writable excelFile = new Writable() {
	@Override
    	public void write(){
        	System.out.println("Save Sheet");
        }
}

위의 코드와 같이 익명 구현 객체를 활용할 수 있다.

보통 new 연산자 뒤에는 인스턴스 생성자가 위치하게 되는데 위의 경우에는 Interface(){}구문이 위치한다. 여기에서 중괄호 안에는 인터페이스의 모든 추상 메소드가 구현되어야한다. 이렇게 익명 구현 객체를 만들어서 사용하면 따로 구현 객체 클래스 파일을 생성하지 않더라도 임시로 구현해서 사용할 수 있다.


인터페이스 상속

인터페이스와 클래스의 관계는 구현 관계인데, 인터페이스와 인터페이스 사이에는 상속 관계가 생길 수 있다. 특히 인터페이스는 다중 상속을 받을 수도 있다.


public interface CodingTest {
	public void solveAlgorithm();
}

public interface Interview {
	public void answerForQuestion();
}

public interface GetJob extends CodingTest, Interview {
	public void passExam();
}

public class JuniorDeveloper implements GetJob {
	public void solveAlgorithm(){
    		System.out.println("문제를 풀었습니다.");
    	}
    	public void answerForQuestion(){
        	System.out.println("질문에 답변했습니다.");
        }
       	public void passExam(){
        	System.out.println("취업했습니다.");
        }

}

위와 같이 인터페이스는 다중 상속을 받아 구현하는 객체에서 상속받은 모든 인터페이스의 추상메소드를 구현하는 것을 확인할 수 있다.


인터페이스와 추상 클래스의 차이

인터페이스와 추상 클래스는 다중 상속을 제외하고는 기능적으로 큰 차이가 없다. 그래서 이렇게 나누어진 이유와 차이점을 이해하기가 어려웠다.

내가 이해한 바로는 추상 클래스와 인터페이스의 차이는 우선 상속과 구현의 차이를 보고 이해하는 것이 빠를 것 같다.

상속은 부모 클래스의 필드나 메소드를 자식 클래스에서 그대로 가져다 쓸 수 있는 편리함과 효율성을 추구하는 기능이다. 또한 자식 클래스가 부모 클래스의 추상화된 속성을 포함하고 있다는 의미가 내포되어있다. 위의 코드를 예로 보아 GetJob은 CodingTest와 Interview에서 상속받는다. GetJob을 위해서는 CodingTest와 Interview를 Pass해야하기 때문에 이 두 인터페이스의 속성을 포함하고 있다. (취업하기위해선 코딩테스트/면접을 통과해야한다.)

구현은 나의 기능이 어떻게 구성되어있는지 미리 정의해놓는 것이다. 바로 가져다 쓰는게 아니라 구현은 구현 클래스에서 따로 해주어야 한다. 바로 예를 들어서 설명하자면 GetJob이라는 기능을 가진 클래스는 JuniorDeveloper이다. (주니어 개발자는 취업을 할 수 있다.) GetJob이란 기능은 JuniorDeveloper가 구현할 수도, SeniorDeveloper가 구현할 수도 있다. 하지만 세부적인 내용은 구현 클래스에 따라 다르게 구현된다.

이렇게 상속과 구현의 차이로 추상 클래스와 인터페이스를 구분지을 수 있다. 위와 같은 차이 때문에 추상 클래스는 상속이라는 큰 개념이 메인 기능이고 구현을 강제해야하는 부분만을 추상메소드로 선언함으로써 구현을 강제하는 기능을 추가한 것이다.

머리속에 있는 것을 최대한 쉽게 꺼내려고 노력했으나.. 횡설수설이 된 것 같아서.. 최종적으로 결론을 내리자면!

추상클래스와 인터페이스의 기능적인 차이는 다중 상속말고는 없다. 하지만 상속과 구현의 차이로부터, 각 용도는 추상클래스는 내가 어떤 속성을 가지는지 상속을 받는 것으로, 인터페이스는 내가 무엇을 하는지를 구현하는 것으로 구분된다.

profile
명확하게 말하고, 꼼꼼하게 개발하자

0개의 댓글