인터페이스란 ?

  • 인터페이스추상클래스처럼 추상메서드를 갖지만 추상클래스보다 추상화 정도가 높아 몸통을 갖춘 일반 메서드 또는 멤버변수를 구성원으로 가질 수 없습니다.
  • 인터페이스는 오직 추상메서드상수만을 멤버로 가질 수 있습니다.
  • 추상클래스와 같이 불완전하므로 그 자체로 사용되기 보다는 다른 클래스를 작성하는 데 도움을 줄 목적으로 사용합니다. 

인터페이스의 작성

  • 선언 시, 키워드로 interface를 사용합니다.
  • 클래스와 같이 접근제어자public 또는 default를 사용할 수 있습니다.
  • 모든 멤버변수public static final 이어야 하며, 이를 생략할 수 있다. ( 컴파일러가 자동으로 추가 )
  • 모든 메서드public abstract 이어야 하며, 이를 생략할 수 있다. ( 컴파일러가 자동으로 추가 )
interface 인터페이스이름 {
	public static final 타입 상수이름 = 값;
    	public abstract 메서드이름 (매개변수목록);
}
인터페이스의 모든 메서드는 추상메서드이어야 하지만, JDK1.8 부터 인터페이스에 static 메서드와 디폴트 메서드 (default method)의 추가를 허용합니다. ( 이 내용은 밑에서 자세히 다룹니다. )

인터페이스의 상속

  • 인터페이스인터페이스로부터만 상속받을 수 있으며, 클래스와 달리 다중상속이 가능합니다.
interface Movable{
	void move(int x, int y)	// (x,y)로 이동하는 메서드
}

interface Attackable{
	void attack(Unit u);	// 지정된 대상( U )을 공격하는 기능의 메서드
}

interface Fightable extends Movable, Attackable{ }	// 인터페이스의 다중 상속
  • Fightable 인터페이스조상 인터페이스 ( Movable, Attackable )에 정의된 멤버를 모두 상속받습니다. 
    따라서, Fightable 인터페이스는 두 개의 추상메서드 move( int x, int y ) attack( Unit u ) 멤버로 갖게 됩니다. 

인터페이스의 구현

  • 인터페이스도 추상클래스처럼 그 자체로는 인스턴스를 생성할 수 없습니다. 
  • 추상클래스상속( extends )을 통해 추상메서드를 완성하는 것처럼, 인터페이스클래스구현( implements )을 통해 완성됩니다.
  • 인터페이스의 메서드 중 일부만 구현한다면, abstract를 붙여서 추상클래스로 선언해야 합니다.
  • 상속구현을 동시에 할 수 있습니다.
class 클래스이름 implements 인터페이스이름 {
	// 인터페이스에 정의된 추상메서드를 구현해야 함.
}

// 인터페이스 구현 예시
class Fighter implements Fightable{
	public void move( int x, int y ) { // 추상 메서드 구현 내용 생략 }
	public void attack( Unit u ) { // 추상 메서드 구현 내용 생략 }
}

// 인터페이스의 메서드 중 일부만 구현하는 경우 abstract를 사용합니다.
abstract class Fighter implements Fightable{
	public void move( int x, int y ) { // 추상 메서드 구현 내용 생략 }
}

// 상속과 구현을 동시에 하는 예시
class Fighter extends Unit implements Fightable{
	public void move( int x, int y ) { // 추상 메서드 구현 내용 생략 }
	public void attack( Unit u ) { // 추상 메서드 구현 내용 생략 }	
}
  • 오버라이딩할 때는 조상메서드보다 같거나 넓은 범위의 접근 제어자를 지정해야 합니다. ( Movable 인터페이스void move( int x, int y )public abstract생략된 것이기 때문에 구현하는 Fighter 클래스에서는 public 접근 제어자를 사용합니다.

인터페이스를 이용한 다형성

  • 자손클래스인스턴스조상타입참조변수참조할 수 있는 것처럼, 인터페이스 역시 이를 구현한 클래스조상이라 할 수 있으므로 인터페이스참조변수로 이를 구현한 클래스인스턴스참조할 수 있습니다. ( 또한 인터페이스 타입으로의 형변환도 가능합니다. ) 
Fightable f = (Fightable)new Fighter();
	또는
Fightable f = new Fighter();
void attack(Fightable f) {	// 인터페이스는 매개변수의 타입으로 사용
	...
}


Fightable method(){	// 메서드의 리턴타입으로 인터페이스의 타입을 지정
	...
	Fighter f = new Fighter();
    return f;
}
  • 인터페이스메서드매개변수타입으로 사용될 수 있습니다. ( Fightable을 구현한 클래스인스턴스매개변수로 넘겨 줄 수 있음 )  
  • 리턴타입이 인터페이스라는 것은 메서드가 해당 인터페이스를 구현한 클래스의 인스턴스를 반환한다는 뜻입니다.

인터페이스의 장점

1. 개발시간을 단축시킬 수 있다.
2. 표준화가 가능하다.
3. 서로 관계없는 클래스들에게 관계를 맺어줄 수 있다.
4. 독립적인 프로그래밍이 가능하다.
  1. 개발시간을 단축시킬 수 있다.
    • 인터페이스가 작성되면, 이를 사용해서 프로그램을 작성할 수 있습니다. 메서드를 호출하는 쪽에서는 메서드의 내용과 관계없이 선언부만 알면 되기 때문입니다. 즉, 인터페이스를 구현하는 클래스가 작성될 때까지 기다리지 않고도 인터페이스를 구현하는 쪽과 동시에 개발을 할 수 있습니다.
  2. 표준화가 가능하다.
    • 프로젝트에 사용되는 기본 틀인터페이스로 작성하고, 이를 구현하여 프로그램을 작성함으로써 일관되고 정형화프로그램개발이 가능해집니다.
  3.  서로 관계없는 클래스들에게 관계를 맺어줄 수 있다.
    •  서로 상속관계에 있지도 않고, 같은 조상클래스를 가지고 있지 않은 서로 아무런 관계가 없는 클래스들에게 하나의 인터페이스공통적으로 구현하도록 함으로써 관계를 맺어 줄 수 있습니다.
  4. 독립적인 프로그래밍이 가능하다.
    • 인터페이스를 이용하면 클래스선언구현분리시킬 수 있기 때문에 실제 구현에 독립적인 프로그램을 작성할 수 있습니다.
    • 클래스클래스간의 직접적인 관계를 인터페이스를 이용해서 간접적인 관계로 변경하면, 한 클래스변경이 다른 클래스에 영향을 미치지 않는 독립적인 프로그래밍이 가능해집니다.

디폴트 메서드와 static 메서드

  • JDK1.8부터 인터페이스에 static 메서드와 디폴트 메서드를 추가할 수 있게 되었습니다.

static 메서드

  • static 메서드인스턴스와 관계 없는 독자적인 메서드입니다.
  • static 메서드접근 제어자는 항상 public이며, 생략할 수 있습니다.

디폴트 메서드

  • 기존 인터페이스메서드추가하는 경우는 추상 메서드추가하는 것으로 인터페이스구현모든 클래스에서 새로운 메서드구현해야하는 번거로움이 존재했습니다. 
  • 디폴트 메서드는 이러한 단점을 고려하여, 추상 메서드의 기본적인 구현제공하는 메서드입니다.
  • 디폴트 메서드추상 메서드아니기 때문에 새로 추가되어도 해당 인터페이스를 구현한 클래스변경하지 않아도 된다는 장점이 있습니다.
  • 키워드 default를 붙이며, 추상 메서드와 달리 일반 메서드처럼 몸통 { }이 있어야 합니다.
  • 접근 제어자public이고 생략이 가능합니다.
  • 새로 추가디폴트 메서드가 기존의 메서드와 이름이 중복되어 충돌되는 경우가 발생할 수 있습니다.
    ( 아래 규칙 참고 )
interface MyInterface{
	void method();
    default void newMethod(){};	// 디폴트 메서드 
}

 

 

이름 충돌을 해결하는 규칙

1. 여러 인터페이의 디폴트 메서드 간의 충돌 
: 인터페이스를 구현한 클래스에서 디폴트 메서드를 오버라이딩해야 한다.

2. 디폴트 메서드와 조상 클래스의 메서드 간의 충돌
: 조상 클래스의 메서드가 상속되고, 디폴트 메서드는 무시된다.

+ Recent posts