언어(Language)/Java

인터페이스(interface)

송기동 2023. 8. 11. 12:13
728x90

인터페이스란?

모든 메서드가 추상 메서드로 선언됨 public abstract

모든 변수는 상수로 선언됨 public static final

자바 8 부터 디폴트 메서드(default method)와 정적 메서드(static method) 기능의 제공으로 일부 구현 코드가 있음

인터페이스 구현과 형 변환

​인터페이스를 구현한 클래스는 인터페이스 형으로 선언한 변수로 형 변환 할 수 있음

상속에서의 형 변환과 동일한 의미

클래스 상속과 달리 구현 코드가 없으므로 여러 인터페이스를 구현할 수 있음 ( cf. extends)

형 변환되는 경우 인터페이스에 선언된 메서드만을 사용가능함

인터페이스가 하는 일

​클래스나 프로그램이 제공하는 기능을 명시적으로 선언

일종의 클라이언트 코드와의 약속이며 클래스나 프로그램이 제공하는 명세(specification)

클라이언트 프로그램은 인터페이스에 선언된 메서드 명세만 보고 이를 구현한 클래스를 사용할 수 있음

어떤 객체가 하나의 인터페이스 타입이라는 것은 그 인터페이스가 제공하는 모든 메서드를 구현했다는 의미임

인터페이스를 구현한 다양한 객체를 사용함 - 다형성

인터페이스를 활용한 dao 구현하기

​DB에 회원 정보를 넣는 dao(data access object)를 여러 DB 제품이 지원될 수 있게 구현함

환경파일(db.properties) 에서 database의 종류에 대한 정보를 읽고 그 정보에 맞게 dao 인스턴스를 생성하여 실행될 수 있게 함

package ch10;

public interface RemoteController {

	// 인터페이스란? 
	// 구현된 것이 아무것도 없는 밑 그림만 있는 기본 설계도 이다. 
	
	// 특징 
	// 멤버 변수, 일반 구현 메서드를 가질 수 없다. 
	// 오직 추상 메서드와 상수만을 멤버로 가질 수 있다. 
	// 인터페이스는 표준, 약속(강제성있는규칙), 규약을 의미한다.
	// 추상클래스보다 추상화가 더 높다. - 기능적인 측면으로 많이 활용한다. 
	
	public static final int SERIAL_NUMBER = 100; // 상수만을 가질 수 있다. 
	//public int number; 멤버 변수 사용 불가 
	
	public abstract void turnOn(); // 추상 메서드만 가질 수 있다. 
	// public void turnOff() {} 인스턴스 메서드를 가질 수 없다. 
	
	// 인터페이스 안에 선언하는 기능은 전부 public abstract 이다. 
	// public abstract 생략 가능하다.
	void turnOff(); 
	
} // end of interface

시나리오 1. 상속 → 추상 클래스 부터 시작해보기

package ch11;

public abstract class HomeAppliances {
	
	int width;
	int height; 
	String color; 
	
	public abstract void turnOn();
	
	public abstract void turnOff();
} // end of class
package ch11;

public class Television extends HomeAppliances {

	@Override
	public void turnOn() {
		System.out.println("TV 전원을 켭니다.");
	}

	@Override
	public void turnOff() {
		System.out.println("TV 전원을 끕니다.");
	}
	
} // end of class
package ch11;

public class Refrigerator extends HomeAppliances {

	@Override
	public void turnOn() {
		System.out.println("냉장고에 전원을 켭니다.");
	}

	@Override
	public void turnOff() {
		System.out.println("냉장고에 전원을 끕니다.");
	}
	
} // end of class
package ch11;

public class ToyRobot {
	
	int width; 
	int height; 
	String color; 
	String name; 
	
	public void turnOn() {
		System.out.println("장난감 로봇을 켭니다.");
	}
	
	public void turnOff() {
		System.out.println("장난감 로봇을 끕니다.");
	}
	
} // end of class

토이로봇을 백색가전 클래스에 상속받게 하면 이상한 OOP(객체 지향 프로그램)가 된다. 


시나리오 2. 인터페이스를 활용해보자.

package ch12;

public interface RemoteController {
	
	// 인터페이스란 
	// 구현된 것이 아무것도 없는 밑 그림만 있는 기본 설계도 
	// 즉, 추상 메서드나 static 상수만을 기본적으로 가진다. 
	
//	public abstract void turnOn(); 
//	public abstract void turnOff(); 
	
	// public abstract 생략이 가능 하다. - 컴파일러가 넣어줌
	void turnOn(); 
	void turnOff();
	
} // end of interface
package ch12;

public interface SoundEffect {

	// 인터페이스 안에 추상 메서드는 
	// 가능한 작게 설계 하는것이 좋다. 
	public abstract void notification();
    
} // end of interface
package ch12;

// 인터페이스를 사용하는 방법 
public class Refrigerator 
	extends HomeAppliances 
	implements RemoteController, SoundEffect {

	
	@Override
	public void turnOn() {
		System.out.println("냉장고에 전원을 켭니다.");
	}

	@Override
	public void turnOff() {
		System.out.println("냉장고에 전원을 끕니다.");
	}

	@Override
	public void notification() {
		System.out.println("띠리리~~링~**");
	}
	
} // end of class
package ch12;

public class Television 
	extends HomeAppliances implements RemoteController {

	@Override
	public void turnOn() {
		System.out.println("티비 전원을 켭니다.");
	}

	@Override
	public void turnOff() {
		System.out.println("티비 전원을 끕니다.");
	}

} // end of class
package ch12;

public class ToyRobot 
	implements RemoteController, SoundEffect {
	
	int width; 
	int height; 
	String color; 
	String name; 
	
	@Override
	public void turnOn() {
		System.out.println("장난감 로봇을 켭니다.");
	}
	
	@Override
	public void turnOff() {
		System.out.println("장난감 로봇을 끕니다.");
	}

	@Override
	public void notification() {
		System.out.println("뚜두두르루~~~");
	}
	
} // end of class
package ch12;

public class MainTest1 {

	public static void main(String[] args) {
		
		// 결론 
		// 코드를 좀 더 유연하고 확장성 있게 
		// 설계할 때 표준, 규약, 규칙을 지켜서 설계하고 싶다면
		// 인터페이스를 활용하자. 
		
		HomeAppliances appliances1 = new Television();
		HomeAppliances appliances2 = new Refrigerator();
		// HomeAppliances appliances3 = new ToyRobot();
		
		RemoteController controller1 = new Television();
		RemoteController controller2 = new Refrigerator();
		RemoteController controller3 = new ToyRobot();
		
		RemoteController[] remoteControllers 
							= new RemoteController[3];
		
		remoteControllers[0] = new Television();
		remoteControllers[1] = new Refrigerator();
		remoteControllers[2] = new ToyRobot();
		
		for (int i = 0; i < remoteControllers.length; i++) {
			//RemoteController remoteController = remoteControllers[i];
			remoteControllers[i].turnOn();;
		}
		
		System.out.println("----------------------------------");
		for (int i = 0; i < remoteControllers.length; i++) {
			//RemoteController remoteController = remoteControllers[i];
			remoteControllers[i].turnOff();
		}
		
	} // end of main

} // end of class
TV 전원을 켭니다.
냉장고 전원을 켭니다.
장난감 로봇을 켭니다.
-------------------------------
TV 전원을 끕니다.
냉장고 전원을 끕니다.
장난감 로봇을 끕니다.
728x90