자바/자바 입문 공부일지

자바 기초 공부 일지 26. 인터페이스interface , 구현implements

Tomitom 2022. 10. 31. 12:20
반응형

 

 

 

●  인터페이스 : 규약, 접점 


user interface (UI) 

유저 인터페이스는 결구구 사용자에게 제공하는 규약이자 접점 입니다. 

사용자가 그것을 통해서 접근할 수 있는 접점입니다. 

 

자바에서 인터페이스는 추상 메소드를 담고 있는 블록입니다. 

추상 메소드란 몸통이 없는 블록입니다. 

즉 메소드의 몸체 없이 선언부분만 있는 메소드이며, 그로인해 인스턴스를 만들 수 없고 참조 변수 선언만 가능한 메소드입니다.

 

인터페이스 클래스는 interface 키워드를 사용해서 접근하며, 다음과 같이 선언합니다. 

 

접근제어자 interface 인터페이스이름 {

    public static final 타입 상수이름 = 값;

    ...

    public abstract 메소드이름(매개변수목록);

    ...

}

 

 

인터페이스 클래스 또한 클래스이지만 클래스와는 달리 인터페이스의 모든 필드는 public static final이어야 하며, 모든 메소드는 public abstract이어야 합니다.

 

만약 이것을 선언하지 않았다고 하더라도, 이것은 공통적으로 적용되는 것이기 때문에 자바 컴파일이 자동으로 부여하기에 생략해도 무관합니다! 

 

인터페이스를 만드는 목적은 클래스에 규칙을 부여하기 위해서 입니다.  (부모 클래스가 아니지만! 부모 클래스의 역할을 합니다!) 

 

클래스를 기반으로 상속할 때의 단점은 부모 클래스가 완성되어 있어야 한다는 것입니다. (부모 클래스 안의 메소드는 몸통을 다 가져야만 합니다.) 하지만 인터페이스는 미완성 메소드를 포함한 부모 클래스가 될 수 있는 것입니다.

 

인터페이스는 참조변수를 만들 수는 있지만, 인스턴스를 생성할 수는 없습니다. (몸체가 없으니까요!) 

 

 

 

● 그렇기 때문에 인터페이스 기반의 자식을 만들 때에는 extends 가 아니라 implements(구현한다는 뜻)으로 상속해야 합니다. 

즉, Printable 에는 print라는 추상 메소드가 있는데, 이것을 사용하기 위해서는 반드시 추상 메소드를 완성시켜야 하고,

그  인터페이스를 구현하기 위해서는 implements 클래스가 있어야 하는 것입니다. 

implements 클래스는 다음과 같이 선언합니다. 


class 클래스이름 implements 인터페이스이름 { ... }

 

class Printer implements Printable {
   public void print(String doc) {   
      System.out.println(doc);
   }
}

 

예제를 하나 더 확인해보겠습니다. 

 

package day16;


interface Player{		// 추상메소드를 완성 
	void training();	// 자동으로 public 이 추가가 되어 있다.  
}

class FootballPlayer implements Player{		// 상속 관계. 어노테이션 사용 가능 
	public void training() {
		System.out.println("열심히 뛴다.");
	}
}

class BaseballPlayer implements Player{
	public void training(){
		System.out.println("야구는 그만 하자.");
	}
}

public class Interface01 {
	public static void main(String[] args) {
	
	}

}

 

●  상속(extend)과 구현(implements)의 차이점 

 

상속은 하나은 하나의 클래스만 상속받을 수 있지만

구현의 경우에는 다중의 인터페이스를 구현할 수 있으며, 상속과 구현을 동시에 할 수 있습니다. 

 

예를 들어 아래와 같습니다. 

class Robot extends Machine implements Movable, Runnable {...}

 

Robot 클래스는 Machine 클래스를 상속하고  MovableRunnable 인터페이스를 구현한 것입니다. 

 

인터페이스는 각각의 클래스에 규칙을 부여하기 위해 필요합니다. 

 

출처 : 윤성우의 열혈 자바 자료집

 

예를 들어 위 이미지에서 보여주고 있는 것처럼 인터페이스를 제공하면

그것을 각각 삼성 혹은 Lg 에서 호환되는 드라이브를 구현하여 실행하는 것입니다.

구체적으로 아래의 예제로 같이 살펴보겠습니다. 

package day16;

interface Printable { 		// MS가 정의하고 제공한 인터페이스
							// Printable 이라는 인터페이스 생성 
	   public void print(String doc);	// 프린트 메소드 
	}

class SPrinterDriver implements Printable {		// 인터페이스 구현화 S프린터드라이브 클래스 생성  
	   @Override
	   public void print(String doc) {		// 오버 라이딩으로 프린트 메소드 완성 
	      System.out.println("From Samsung printer");
	      System.out.println(doc);
	    }
	}

	class LPrinterDriver implements Printable {	//인터페이스 구현화 L프린터드라이브 클래스 생성
	   @Override
	   public void print(String doc) {		//오버 라이딩으로 프린트 메소드 완성 
	      System.out.println("From LG printer");
	       System.out.println(doc);
	    }
	 }


public class PrinterDriver {

	public static void main(String[] args) {
	
		   String myDoc = "This is a report about...";	// 각 프린터 드라이브 아래에서 출력될 문장 
		   
		   // 삼성 프린터로 출력
		   Printable prn = new SPrinterDriver();	// S 프린터 드라이브로 prn 생성자 생성 
		   prn.print(myDoc);		// S프린터 드라이브에서 오버 라이딩 된 문서 출력 
		   System.out.println();

		   // LG 프린터로 출력
		   prn = new LPrinterDriver();		// 생성자 prn 을 L 프린터 드라이브 클래스로 정의 
		   prn.print(myDoc);		// L 프린터 드라이브에서 오버 라이딩 된 문서 출력 
		}
	
	}

 

순서대로 각 각주에 설명을 기재했으니 참고해주세요.

그럼 상기 기재된 코드대로 인터페이스를 선언했을 경우 발생할 수 있는 문제점이 있습니다.

 

 

만약 새로운 기능을 추가 하기 위해 인터페이스 클래스에 새로운 메소드를 추가했을 경우에 

해당 클래스를 상속받아 구현한 클래스들은  해당 인터페이스의 모든 추상 메소드를 구현해야만 인스턴스 생성이 가능하므로

매번 새로운 기능에 대한 메소드를 추가로 구현해야 한다는 문제점이 있습니다. 

 

이를 해결하기 위해서 인터페이스 간의 상속도 extends 로 표현해서 인터페이스를 상속받아 사용할 수 있습니다. 

 


interface Printable { 
   public void print(String doc);
}

interface ColorPrintable extends Printable{
void printCMYK(String doc);
}

 

<기존 클래스는 수정할 필요 없습니다. > 
class SPrinterDriver implements Printable {
   @Override
   public void print(String doc) {
      System.out.println("From Samsung printer");
      System.out.println(doc);
    }
}

class LPrinterDriver implements Printable {
   @Override
   public void print(String doc) {
      System.out.println("From LG printer");
       System.out.println(doc);
    }
 }

 

<여기에서 새로운 기능을 추가>

 

class Prn909Drv implements ColorPrintable {
   @Override
   public void print(String doc) {   // 흑백 출력
      System.out.println("black & white ver");
      System.out.println(doc);
   }
   
   @Override
   public void printCMYK(String doc) {   // 컬러 출력
      System.out.println("CMYK ver");
      System.out.println(doc);
   }
}

반응형