1. 인터페이스(Interface)
- 객체의 사용 방법을 정의한 타입으로 객체의 교환성을 높여줌 → 다형성을 구성하는 매우 중요한 역할
- interface 키워드로 선언, 클래스 이름 뒤에 implements 키워드로 구현
- 상수와 메서드만을 구성멤버로 가짐
- 데이터를 저장할 수 없기 때문에 데이터를 저장할 객체 또는 정적 변수 선언 불가능
- 인터페이스 선언된 변수는 public static final을 생략하더라도 자동으로 붙음
- 인터페이스의 메서드를 추상메서드 형식으로 선언하면 abstract를 생략하더라도 자동으로 붙음
- extends 키워드를 사용하여 인터페이스 간의 상속 구현 가능, 다중 상속 표현 가능
public interface RemoteController {
// 최대 배터리량, 최소 배터리량을 상수로 지정
int MAX_BATTERY = 100;
int MIN_BATTERY = 0;
// 리모콘이 가져야 하는 필수 기능에 대해서만 정의
public void turnOn();
public void turnOff();
public void showStatus();
}
public class TVRemoteController implements RemoteController {
private final int inch;
private int channel;
public TVRemoteController(int inch) {
this.inch = inch;
this.channel = 1;
}
@Override
public void turnOn() {
System.out.println("TV를 켭니다.");
}
@Override
public void turnOff() {
System.out.println("TV를 끕니다.");
}
@Override
public void showStatus() {
System.out.println("화면크기 : " + this.inch);
System.out.println("채널 : " + this.channel);
}
public void setChannelDown() {
// 1번까지만 채널이 있음
if(this.channel - 1 < 1) {
this.channel = 1;
} else {
this.channel--;
}
}
public void setChannelUp() {
this.channel++;
}
}
public class RobotCleanerRemoteController implements RemoteController{
public String modelName;
public String price;
// 로봇청소기 생성자
public RobotCleanerRemoteController(String modelName, String price) {
this.modelName = modelName;
this.price = price;
}
@Override
public void turnOn() {
System.out.println("로봇청소기를 켭니다.");
}
@Override
public void turnOff() {
System.out.println("로봇청소기를 끕니다.");
}
// 로봇청소기에 맞는 정보조회
@Override
public void showStatus() {
System.out.println("모델명 : " + this.modelName);
System.out.println("가격 : " + this.price);
}
}
public class MainClass {
public static void main(String[] args) {
// 인터페이스 역시 구현체를 다형성 형식으로 받을 수 있음
RemoteController rc = new TVRemoteController(50);
//RemoteController rc = new RobotCleanerRemoteController("imou", "280000");
rc.turnOn();
rc.showStatus();
rc.turnOff();
}
}
위와 같이 인터페이스를 이용하여 해당하는 타입의 객체를 생성할 수 있고, 해당 객체에서 구현한 함수에 따라 내용이 다르게 출력, 즉 다형성이 활용되는 것을 확인할 수 있다.
2. has - a 관계
- 상속의 전제는 is - a 관계
- 현실에서는 is - a 관계가 아니더라도 다른 객체의 기능을 쓸 수 있는 경우가 많음
→ has - a 관계로 설정해 객체 간 사용 구현
※ 현업에서는 상속보다 합성을 많이 이용한다.
public class Gun {
private int bullet;
private String modelName;
private String gunNumber;
public Gun(String modelName, String gunNumber) {
this.bullet = 5;
this.modelName = modelName;
this.gunNumber = gunNumber;
}
public void shoot() {
if(this.bullet > 0) {
this.bullet--;
System.out.println("총을 쐈습니다.");
} else {
System.out.println("방아쇠를 당겼지만 총알이 없습니다.");
}
}
public void reload() {
this.bullet = 5;
}
}
public class Police {
// 상속 없이 Gun 기능을 사용하기 위해 멤버변수도 Gun을 가짐
private Gun gun;
private String name;
private int height;
public Police(Gun gun, String name, int height) {
this.gun = gun;
this.name = name;
this.height = height;
}
public void shoot() {
this.gun.shoot();
}
public void showStatus() {
System.out.println("소유총기 : " + this.gun);
System.out.println("총기이름 : " + this.name);
System.out.println("총기크기 : " + this.height);
}
}
public class MainClass {
public static void main(String[] args) {
// Gun을 new 키워드로 생성해야 Police 생성자에 전달 가능
Gun gun = new Gun("M-16", "369486");
// Gun을 사전에 생성하지 않으면 넘길 방법이 없음
Police police = new Police(gun, "나경찰", 180);
police.shoot();
police.shoot();
police.shoot();
police.shoot();
police.shoot();
police.shoot();
}
}