본문 바로가기
[JAVA]/[자바 기초]

[자바 기초] 인터페이스 (Interface)

by 북방바다코끼리표범 2023. 8. 11.

복습

https://shins99.tistory.com/37

 

[자바 기초] String 클래스

복습 https://shins99.tistory.com/36 [자바 기초] 템플릿 메서드 패턴 (Template Method Pattern) 복습 https://shins99.tistory.com/35 [자바 기초] 추상 클래스 복습 https://shins99.tistory.com/34 [자바 기초] 다형성 복습 https:/

shins99.tistory.com


💡 학습 목표 

1. 인터페이스에 대한 기본 개념 
2. 문법적인 부분을 살펴 보자.

 

인터페이스 (Interface)

- 구현된 것이 아무것도 없는 밑 그림만 있는 기본 설계도

 

특징

- 멤버 변수, 일반 구현 메서드를 가질 수 없음

  → 오직 추상 메서드와 상수만을 메서드로 가질 수 있음

- 인터페이스는 표준 → (기능을 정의해두면, 어떤 클래스에서든 가져와서 사용 가능)

  약속 → (강제성 있는 규칙) 

  규약을 의미

- 구현하는 클래스가 어떤 메서드를 반드시 구현해야 하는지 지시함

- 추상 클래스보다 추상화가 더 높음 = 기능적인 측면으로 많이 활용, 더 유연한 코드설계 가능

 

장점

- 추상화

: 구현과 독립적인 동작 제공 (높은수준으로 시스템 이해, 설계 가능)

- 다중 상속 

: 인터페이스는 여러 개 구현 가능

- 다형성

:  하나의 객체를 클래스타입, 구현된 인터페이스 타입 두 개로 볼 수 있음 (유연성 높음, 다른 클래스와 결합도 낮춤)

 

인터페이스 구현

- 하나의 클래스에 여러 인터페이스 구현 가능 = 인터페이스명 ,(콤마) 인터페이스명

- 인터페이스 구현한 클래스는 업캐스팅, 다운캐스팅 가능

 → 업 캐스팅 = 인터페이스명 참조변수 =  new클래스명();

 → 다운 캐스팅 = (클래스명) 참조변수

 

단일 책임의 원칙

- 하나의 클래스는 하나의 목적을 위해 설계

- 하나의 인터페이스는 하나의 목적을 위해 설계

→ 내부의 메서드 수가 적을수록 좋음

 

	public static final int SERIAL_NUMBER = 100; // 상수만을 가질 수 있다. 
	//public int number; 멤버 변수 사용 불가 
	
	public abstract void turnOn(); // 추상 메서드만 가질 수 있다. 
	// public void turnOff() {} 인스턴스 메서드를 가질 수 없다. 
	
	// 인터페이스 안에 선언하는 기능은 전부 public abstract 이다. 
	// public abstract 생략 가능하다.
    // 컴파일러가 자동으로 넣어준다.
	void turnOff();

시나리오 1 - 상속 → 추상 클래스 부터 시작

 

package ch11;

public abstract class HomeAppliances {
	
	int width;
	int height; 
	String color; 
	
	public abstract void turnOn();
	
	public abstract void turnOff();
}

package ch11;

public class Television extends HomeAppliances {

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

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

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("장난감 로봇을 끕니다.");
	}
}
: 토이로봇을 백색가전 클래스 상속받게 하면 이상한 OOP 가 된다.

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

package ch12;

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

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("띠리리~~링~**");
	}
	
}

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("뚜두두르루~~~");
	}
	
}

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();
		}
		
		
		
		
	}

}