[Java8] 인터페이스 default 메소드 사용 예제와 인터페이스 메서드 추가 유연하게 구현방법

반응형
728x90
반응형

상황분석

우리에게 운영중인 레거시 프로젝트가 있다고 가정해보자. 그리고 UserDto 파일이 존재하는데, 해당 Dto 파일은 User 테이블의 필드들을 담고있는 클래스이다.

 

  • UserDto.java
public class UserDto implements CommonUser {
    private String name;
    private String gender;
    private String age;

    public UserDto(String name, String gender, String age) {
        this.name = name;
        this.gender = gender;
        this.age = age;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public String getGender() {
        return gender;
    }

    @Override
    public String getAge() {
        return age;
    }
}

 

그리고 UserDto가 CommonUser 인터페이스를 상속하고있다. 

 

  • CommonUser.java
public interface CommonUser {
    public String getName();
    public String getGender();
    public String getAge();
}

 

 

수정건 발생

CommonUser 인터페이스를 구현한 클래스는 UserDto 뿐만이 아닌 각 서비스에 맞는 여러개의 Dto가 있다. 그리고 우리는 유저들을 개발 부서의 유저들을 따로 관리하기 위해 부서 정보를 가져오는 getDept() 메서드를 추가해야했다.

 

  • CommonUser.java
public interface CommonUser {
    public String getName();
    public String getGender();
    public String getAge();
    public String getDept();
}

 

인터페이스에 getDept() 메서드를 추가하였는데 해당 CommonUser 인터페이스를 상속하고있는 모든 클래스에서 에러가 발생했다. 

 

Class 'UserDto' must either be declared abstract or implement abstract method 'getDept()' in 'CommonUser'

 

당연한 이유다. 인터페이스의 메소드를 구현해야하는 자식 클래스가 getDept() 메소드 추가에 대응을 못했기 때문에 발생한 에러다.

 

 

 

 

default 메서드 사용

  • CommonUser.java
public interface CommonUser {
    public static final String deptName = "dev";
    
    public String getName();
    public String getGender();
    public String getAge();
    
    default public String getDept() {
        return CommonUser.deptName;
    }
}

 

getDept 메소드를 default 메소드로 선언하였다. 이렇게되면 기존에 이미 CommonUser 인터페이스를 상속하던 클래스들의 수정 없이 getDept() 메소드를 추가하여 새로 추가된 개발 부서의 유저 관리 DTO를 얼마든지 생성할 수 있다. 여기서 기존 클래스들의 수정의 필요성이 없어졌다는 점에서 유연성이 매우 높아졌다고 볼 수 있다. default 메소드의 경우 default가 생략이 가능하지만 명시적으로 default 메서드임을 정의하는 것이 좋다. default가 없다면 위 getName(), getGender() 등의 기존 인터페이스 메서드와 구분할 방법이 없다.

 

  • UserDto.java
public class UserDto implements CommonUser {
    private String name;
    private String gender;
    private String age;

    public UserDto(String name, String gender, String age) {
        this.name = name;
        this.gender = gender;
        this.age = age;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public String getGender() {
        return gender;
    }

    @Override
    public String getAge() {
        return age;
    }

    /**
     * default 메서드 오버라이드
     * @return
     */
    @Override
    public String getDept() {
        /* java8 추가) super 키워드를 이용해서 default 메서드를 호출하는 기능 사용 */
        return CommonUser.super.getDept();
    }
}

 

마지막으로 UserDto 클래스 안에 default 메서드를 오버라이드하여 정의하였다. super 연산자를 사용하여 인터페이스의 메소드를 호출할 수 있다.

 

 

반응형

Designed by JB FACTORY