인터페이스는 클래스의 일종으로, 클래스가 자료형인 것처럼 인터페이스도 마찬가지로 자료형이다.
인터페이스는 상속받는 여러 클래스들을 행동(사용법, 메소드)들을 통일시키는 역할을 하며, 이를 행동 규약을 정의한다고 한다. 따라서 인터페이스는 관계 형성에 많이 사용되고 있다.
인터페이스는 객체를 생성할 수 없지만, 참조 변수는 생성할 수 있다는 특징이 있다.
💡인터페이스 특징
1. 구현된 멤버를 가질 수 없다.
인터페이스는 클래스와 달리 멤버 변수를 가질 수 없다. 그리고 메소드 역시 구현부 또한 소유할 수 없다.
2. 클래스의 부모 역할을 한다.
인터페이스는 클래스의 부모 역할을 하며, 클래스가 인터페이스를 상속받을 수 있다.
이를 통해 다중 상속의 문제를 방지할 수 있고, 상속받는 클래스마다 공통된 기능을 제공할 수 있게 한다.
3. 다중 상속이 가능하다.
자바에서 클래스는 다중 상속이 허용되지 않는 반면, 인터페이스에서 다중 상속이 가능하다.
인퍼페이스는 구현부가 없고 껍데기만 만들어 놓기 때문에 다중 상속으로 문제가 생기더라도 찾기 쉽다.
💡인터페이스의 활용
인터페이스는 직접적으로 객체를 생성할 수 없으며, 구현부를 포함하지 않는 추상 메소드만을 가질 수 있다. 이러한 인터페이스의 특징을 소스코드를 살펴보며 이해해 보도록 하자.
interface Mouse {
// 추상 메소드 선언
void click();
}
class M705 implements Mouse {
// 인터페이스의 추상 메소드 구현
public void click() {
// 클릭 동작 구현
}
}
class G304 implements Mouse {
// public void push() {
// System.out.println("클릭!!");
// }
@Override
public void click() {
System.out.println("클릭!!");
}
}
public class InterfaceExample {
public static void main(String[] args) {
Mouse m1 = new M705(); // 인터페이스 변수로 구현된 클래스의 객체 참조
m1.click(); // 객체의 클릭 동작 호출
G304 m3 = new G304(); // 인터페이스 변수로 구현된 클래스의 객체 참조
m3.click(); // 객체의 클릭 동작 호출
}
}
Mouse 인터페이스
interface Mouse {
// 추상 메소드 선언
void click();
}
Mouse 인터페이스 클래스의 click() 메소드는 구현부 없이 선언부만 가지고 있는 것을 볼 수 있다.
이는 인터페이스가 구현된 멤버를 가질 수 없다는 특징을 반영한 것으로, Mouse 인터페이스 내에는 Mouse로서 갖춰야 할 행동을 정의하면 된다.
인터페이스는 오직 선언부에만 해당하며, 구현부가 될 수 없다는 것을 명심하자.
Mouse 인터페이스를 상속받는 M705 클래스
class M705 implements Mouse {
// 인터페이스의 추상 메소드 구현
public void click() {
// 클릭 동작 구현
}
}
마트에서 M705 마우스를 구매해서 사용하기로 했다. M705는 Mouse의 click() 메소드를 구현한다.
Mouse 인터페이스를 상속받는 G304 클래스
class G304 implements Mouse {
// public void push() {
// System.out.println("클릭!!");
// }
@Override
public void click() {
System.out.println("클릭!!");
}
}
M705 마우스를 사용하다가 고장이 나서 G304 마우스를 새로 구매하려고 한다.
그런데 G304 마우스는 click() 하는 방식이 아니라 push() 하는 방식으로 사용하는 마우스였다.
하지만 마우스에 push() 메소드를 구현하려고 하면 오류가 난다. 그 이유는 Mouse 인터페이스에 선언되어 있지 않기 때문이다.
이처럼 인터페이스는 클래스의 부모 역할을 하게 되며, 자신이 가지고 있는 추상 클래스를 자식 클래스에게 강제로 만들도록 시키는 역할을 가지고 있다고 볼 수 있다.
이를 통해 인터페이스는 사용자의 경험을 극단적으로 높이고, 생산성을 높여주는 기능을 한다.
💡인터페이스 다중 상속
public class Ex_interface {
public static void main(String[] args) {
사람 isaac = new 사람();
isaac.출근();
isaac.업무();
isaac.퇴근();
isaac.요리();
isaac.청소();
isaac.수면();
}
}
interface 회사 {
void 출근();
void 퇴근();
void 업무();
}
interface 가정 {
void 요리();
void 청소();
void 수면();
}
class 사람 implements 회사, 가정 {
@Override
public void 출근() {
}
@Override
public void 퇴근() {
}
@Override
public void 업무() {
}
@Override
public void 요리() {
}
@Override
public void 청소() {
}
@Override
public void 수면() {
}
}
인터페이스는 때와 장소에 따른 자격(role)으로 볼 수 있다.
어떤 객체는 꼭 하나의 역할만 하는 것이 아니다. 때에 따라 다른 역할을 할 수 있다는 점을 기억하자.
이처럼 사람 클래스로 만든 isaac 객체는 회사와 가정에서 하는 역할을 각각 다르게 할 수 있다.
class Lee implements 회사 {
}
class Park implements 가정 {
}
새로운 클래스가 만들어지면 그 부모가 누구인지를 먼저 확인하는데, 인터페이스를 구분할 경우 자식 클래스가 어떤 성격인지 이해하기 쉽고, 유연하게 대처가 가능하다.