인도네시아 생활기

[JAVA/개발] 인터페이스(interface) 본문

PROGRAMMING/JAVA

[JAVA/개발] 인터페이스(interface)

인니외노자 2020. 7. 22. 01:41

인터페이스(Interface)

 

인터페이스는 일종의 추상클래스

 

추상메서드를 갖지만 추상클래스보다 추상화 정도가 높아서 추상클래스와 달리 몸통을 갖춘 일반 메서드 또는 멤버변수를 구성원으로 가질 수 없다.

 

오직 추상메서드와 상수만을 멤버로 가질 수 있다.

 

추상클래스처럼 완성되지 않은 상태로 사용하는 것이기에 그 자체보다 다른 클래스 작성에 도움을 주기 위해 사용한다.

 

사용방법은 아래와 같다.

interface 인터페이스이름 {
	public static final 타입 상수이름 = 값;
    	public abstract 메서드이름(매개변수목록);
}

일반적인 클래스와는 다르게 인터페이스의 멤버들은 제약사항이 존재한다.

 

  • 모든 멤버변수는 public static final 이어야하며 이를 생략 가능하다.
  • 모든 메서드는 public abstract 이어야하며 이를 생략 가능하다.

인터페이스에 정의된 경우에는 모든 멤버에 대해서 예외가 없이 적용되는 사항이기 때문에 제어자를 생략할 수 있고, 편의상 생략하는 경우가 많다.

 

interface PlayingCard{
	public static final int SPADE = 4;
    	final int DIAMOND = 3;		//public static final int DIAMOND = 3;
    	static int HEART = 2;		//public static final int HEART = 2;
    	int CLOVE = 1				//public static final int DIAMOND = 1;
    
    	public abstract String getCardNumber();
    	String getCardKind();		//public static final int DIAMOND = 3;
}

 

인터페이스(Interface)의 장점

그렇다면 인터페이스를 사용하는 이유는 무엇인가?

 

  • 개발시간의 단축기 가능하다.
  • 표준화가 가능하다.
  • 서로 관계없는 클래스들에게 관계를 맺어줄 수 있다.
  • 독립적인 프로그래밍이 가능하다.

인터페이스(Interface)의 상속

 

인터페이스는 인터페이스로부터 상속을 받을 수 있다. 클래스와 달리 다중상속이 가능하다.

 

클래스와 달리 Object 클래스와 같은 최상단에 위치하는 조상이 없다는 점도 유의하자.

 

클래스의 상속과 마찬가지로 자손 인터페이스는 조상 인터페이스에 정의된 멤버를 모두 상속 받는다. 

 

interface Steering{
	//차량을 조향
    void Steer(int x, int y);
}

interface Moving{
	//차량을 앞뒤로 이동
    void Move(Unit u);
}

interface Driving extends Steering, Moving{}

즉, 위의 코드에서 보면 Driving은 Steering과 Moving을 각각 조상 인터페이스로 두고 상속 받아  Steer(int x, int y), Move(Unit u)를 모두 멤버로 갖게 됨을 의미한다. 

 

인터페이스(Interface)의 구현

추상클래스와 마찬가지로 인터페이스도 그 자체로는 인스턴스를 생성할 수 없으며, 추상클래스가 상속을 통해 추상메서드를 완성하는 것처럼, 인터페이스도 자신에 정의된 추상메서드의 몸통을 만들어주는 클래스를 작성할 필요가 있다. 

 

이는 추살클래스가 자신을 상속받는 클래스를 정의하는 것과 같다. 

 

하지만 클래스를 확장한다는 의미의 키워드인 extends를 사용하지만 인터페이스는 구현한다는 의미의 키워드 implements를 사용한다.

 

class 클래스이름 implements 인터페이스이름 {
//인터페이스에 정의된 추상메서드를 모두 구현해야한다.
}

class Drive implements Driving{
	public void Steer(int x, int y){ .... }
    	public void Move(Unit u){....}
}

위와 같은 상황에서 Drive 클래스는 Driving인터페이스를 구현한다 라는 표현을 사용한다. 

 

단, 구현하는 인터페이스의 메서드 일부만 구현한다면 , abstract를 붙여서 추상클래스로 선언해야한다.

 

abstract class Drive implements Driving{
	public void Steer(int x, int y){ .... }
}

 

상속과 구현을 동시에 하는 경우는 다음과 같다.

class Drive extends Unit implements Driving{
	public void Steer(int x, int y){ .... }
    	public void Move(Unit u){....}
}

 

다형성

 

인터페이스의 다형성을 가기 앞서 다형성을 설명하자면 다음과 같다

 

다형성이란 여러 가지 형태를 가질 수 있는 능력을 의미하며, 자바에서는 한 타입의 참조변수로 여러 타입의 객체를 참조할 수 있도록 함으로써 다형성을 구현하였다. 

 

즉, 구체적으로는 조상클래스 타입의 참조변수로 자손클래스의 인스턴스를 참조할 수 있도록 하였다는 것!

 

class Tv{
boolean power;
	int channel;
    
    void power(){
    power = !power;
    }
    void channelUp(){
    ++channel;
    }
    void channelDown(){
    --channel;
    }
}

class CaptionTV extends TV{
String text;
	void caption(){ .... } 
}

위의 코드 상에서 보면 Tv 인스턴스를 사용하기 위해서 Tv 타입의 참조변수를 사용하였고, CaptionTv인스턴스를 다루기 위해서는 CaptionTv타입의 참조변수를 사용한 것을 알 수 있다. 

 

일반적으로는 인스턴스 타입과 참조변수 타입이 일치하는 것이 보통이지만, Tv와 CaptionTv클래스가 서로 상속관계에 있을 경우, 조상 클래스 타입의 참조변수로 자손클래스의 인스턴스를 참조하는 것도 가능하다.

Tv t = new CaptionTv(); //타입 불일치, 조상타입의 참조변수로 자손 인스턴스를 참조

 

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

기존의 다형성에서는 자손클래스의 인스턴스를 조상타입의 참조변수로 참조하는 것이 가능하다는 것이 있었다. 여기서 인터페이스 또한 이를 구현한 클래스의 조상이라고 할 수 있고, 해당 인터페이스 타입의 참조변수로 이를 구현한 클래스의 인스턴스를 참조할 수 있으며, 인터페이스 타입으로의 형변환도 가능하다.

 

즉 다음의 코드를 살펴보자.

Moving m = (Moving) new Move();
또는
Moving m = new Move();

인터페이스 Moving을 클래스 Move가 구현했을 때, 위의 형태로 나타낼 수 있음을 알 수 있다.

 

위의 형태를 참조하면 인터페이스는 다음과 같이 메서드의 매개변수의 타입으로도 사용될 수 있음을 알 수 있다.

void Drive(Moving m){
....................
}

매개변수의 의미는 메서드 호출 시 해당 인터페이스를 구현한 클래스의 인스턴스를 매개변수로 제공을 해야한다는 점이다.

class Drive extends Unit implements Driving{
	pubic void Steer(int x, int y){ ..... }
	public void Move(Driving d){ .....}
    }

위에서 보는 바와 같이 Driving인터페이스를 구현한 Drive 클래스가 있을 때, Move 메서드의 매개변수로 Drive 인스턴스를 넘겨줄 수 있다. 

 

즉 이는 Move(new Drive()) 와 같이 나타낼 수 있다는 것이다.

 

이는 아래처럼 메서드의 리턴타입으로 인터페이스를 지정할 수도 있다.

 

Driving method(){
	...
	Drive d = new Drive();  
	return d;
}

위 코드에서 두 문장을 한 문장으로 바꾸면 return new Drive();  와 같다.

 

즉, 리턴타입이 인터페이스라는 것은 메서드가 해당 인터페이스르 구현한 클래스의 인스턴스를 반환한다는 것을 의미한다. 

Comments