본문 바로가기

JAVA

추상 클래스 예제 - 운전면허

운전을 하려면 운전면허가 필요하다.

 

운전면허는 여러 종류가 있지만 여기선 간단히 두 종류 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