운전을 하려면 운전면허가 필요하다.
운전면허는 여러 종류가 있지만 여기선 간단히 두 종류 1종 보통, 2종 보통으로 나누겠다.
1종 보통 면허는 2종 보통의 상위호환으로, 2종 보통 면허가 필요한 차량은 운전할 수 있다.
반대로 2종 보통은 1종 보통 면허를 필요로 하는 몇몇 차량을 운전할 수 없다.
1종 보통은 자동, 수동 승용차를 운전할 수 있지만,
2종 보통은 수동 승용차를 운전할 수 없는 점이 그 예이다.
위의 예시는 다음과 같이 만들 수 있다.
// Car.java - 자동차 클래스
public class Car{}
// ManualCar.java - 자동차 클래스를 부모로 하는 수동 승용차 클래스
public class ManualCar extends Car{}
// AutoCar.java - 자동차 클래스를 부모로 하는 자동 승용차 클래스
public class AutoCar extends Car{}
// 2종보통 소지자
public class AutoDriver {
// 특정 차를 운전하는 메서드
public void drive(Car c) { // AutoCar, ManualCar 클래스 인스턴스 둘 다 입력 가능
// 자동차 운전 가능 여부 판별
if(canDrive(c))
System.out.println("부릉부릉");
else
System.out.println("자격이 없습니다.");
}
// 운전 가능한 차인지 판별
public boolean canDrive(Car c){
// 자동 승용차가 아니면 운전 불가
if(c.getClass().equals(AutoCar.class))
return true;
else
return false;
}
// 1종보통 소지자
public class ManualDriver {
// 특정 차를 운전하는 메서드
public void drive(Car c) {
if(canDrive(c))
System.out.println("부릉부릉");
else
System.out.println("자격이 없습니다.");
}
// 운전 가능한 차인지 판별
public boolean canDrive(Car c){
// 모든 차 운전 가능
return true;
}
1종보통 및 2종보통 소지자는 운전(drive 메서드)을 할 수 있고,
운전하고자 하는 차를 본인이 몰 자격이 있는지 확인(canDrive 메서드)해야 한다.
코드를 위와 같이 짤 수는 있지만, 보다시피 운전면허 소지자는 drive()와 canDrive()라는 동일한 이름의 메서드가 있다.
더 나아가 drive() 메서드 두 클래스간 차이가 없으므로 코드의 반복이 발생한다.
코드의 반복은 유지보수를 하는데 있어 번거롭기 때문에 해소해줄 필요가 있고,
이는 추상 클래스 개념을 활용하여 해소할 수 있다.
1종보통 소지자와 2종보통 소지자의 공통점은 바로 둘 다 '운전자'라는 점이고,
이를 고려하여 두 클래스의 부모 클래스를 '운전자(Driver)'로 둘 수 있다.
하지만 부모 클래스의 운전자는 아직 어떤 운전면허를 소지하고 있는지 정의하지 않았기 때문에,
해당 클래스에서 canDrive() 메서드를 구현하기엔 성급한 면이 있다.
이 구현을 더 구체적인 자식 클래스(운전면허 종류가 정해진 클래스)에게 떠넘길 수가 있고,
이때 추상 클래스 개념을 사용하는 것이다.
// Driver.java - 운전면허 소지자 추상 클래스
public abstract class Driver {
public void drive(Car c) {
if(canDrive(c))
System.out.println("부릉부릉");
else
System.out.println("자격이 없습니다.");
}
// 구현되지 않은 추상 메서드
public abstract boolean canDrive(Car c);
}
// AutoDriver.java - 2종보통 소지자 클래스
public class AutoDriver extends Driver{ // 운전자 추상 클래스를 부모로 삼는다
// 추상 메서드 구현
@Override
public boolean canDrive(Car c) {
if(c.getClass().equals(AutoCar.class))
return true;
else
return false;
}
}
// ManualDriver.java - 1종보통 소지자 클래스
public class ManualDriver extends Driver {
// 추상 메서드 구현
@Override
public boolean canDrive(Car c) {
return true;
}
}
Driver라는 추상 클래스가 추가되었고, canDrive() 메서드는 추상 메서드로 남겨지고 아직 구현되지 않는다.
그 이후 각 면허 소지자는 해당 추상 클래스를 상속받고, 구현되지 않은 canDrive() 메서드를 구현한다.
이렇게 작성하면 동일한 운전 메서드 코드를 반복할 필요가 없어지고,
추후 다른 면허증 소지자를 추가할 때 Driver 추상 클래스를 상속받아 canDrive() 메서드만 추가로 구현하면 된다.
'JAVA' 카테고리의 다른 글
제네릭 인터페이스 예시 (0) | 2020.01.06 |
---|---|
Enumeration Type에 대하여 (0) | 2020.01.05 |
포장 클래스와 등호(==) (0) | 2020.01.04 |
클래스 상속의 함정 (0) | 2020.01.02 |
반복 코드 제거 - Constructor Chaining, Initialization Blocks (0) | 2020.01.01 |