본문 바로가기
카테고리 없음

[Java] Inheritance vs Delegation (상속과 위임)

by 왕 달팽이 2019. 7. 2.
반응형

객체지향 프로그래밍에서 클래스를 설계할 때 상속(Inheritance)과 위임(Delegation) 방식을 고민하게 된다. 상속(Inheritance)과 위임(Delegation) 방식의 차이점과 어떤 상황에서 뭘 써야할지에 대해 알아보자.

 

클래스의 상속(Inheritance)

객체지향 프로그래밍 언어에서 클래스를 상속(Inheritance)을 통해 정의할 수 있다.

class Person {

    protected int age;
    
    protected String name;
    
    public Persion(int age, String name) {
    	this.age = age;
        this.name = name;
    }
    
    public int getAge() {
    	return this.age;
    }
    
    public String getName() {
    	return this.name;
    }
}

age와 name이라는 멤버 변수를 가지고 있는 Person 클래스를 생각해보자. 이 클래스를 상속 받는 Student 클래스는 다음과 같이 정의할 수 있다.

class Student extends Person {
	
    protected String studentNumber;
    
    public Student(int age, String name, String studentNumber) {
    	
        super(age, name);
        this.studentNumber = studentNumber;
    }
    
    public String getStudentNumber() {
    
        return this.studentNumber;
    }
}

'extends'라는 키워드를 이용해서 Person 클래스를 상속받아 확장하여 Student 클래스를 정의했다. Student 클래스 정의에는 직접적으로 나와있지 않지만 부모 클래스인 Person 클래스의 메소드인 getAge()와 getName() 메소드를 호출 할 수 있다.

 

일반적으로 두 클래스 간의 관계가 'IS-A' 관계이면 상속을 사용한다. Student is a person이므로 상속을 통해서 클래스를 정의하는게 자연스럽다.

 

클래스의 위임(Delegation)

상속(Interitance)과 다르게 위임(Delegation)은 다른 클래스의 객체를 멤버로 갖는 형태의 클래스 정의다.

class Employee {
    
    private Department department;
    
    private String name;
    
    publiv Employee(String name, Department department) {
        
        this.name = name;
        this.department = department;
    }
    
    public String getDepartmentName() {
    
        return this.department.getName();
    }
}

이 경우 특정 메소드 호출을 멤버 클래스의 메소드에 포워드(Forward)하는 식으로 구현하게 된다. 

 

Employee 클래스와 Department 클래스 사이의 관계를 살펴보면 'IS-A' 관계는 아니다. (Employee is a Department는 어색하다.) 따라서 멤버 변수로 Department 클래스를 포함하는 Delegation 형태로 구현을 했다.

 

언제 무엇을 써야하나?.

두 가지 방법중에 하나가 무조건 우월한 것은 아니다. 상황에 따라서 적당한 방법을 사용해야 한다. 일반적으로는 다음과 같은 판단 기준을 가지고 있으면 된다. 

 

  • 두 클래스의 관계가 'IS-A' 관계이면 상속(Inheritance)을 써야한다.
  • 기존에 존재하는 API에 넘겨줘야 하는 경우 상속(Inheritance)을 써야한다.
  • final 클래스를 확장하고 싶은 경우 위임(Delegation)을 써야한다.

개발자 중에 코드를 재사용하겠다고 상속을 남발하는 경우가 있다. 당장 작성해야하는 코드는 줄어들어서 효율적인 것처럼 보인다. 

 

하지만 상속을 사용해서 클래스를 정의한 경우, 부모 클래스와 자식 클래스 사이에는 강한 연관관계가 생기게 된다. (Tightly-Coupled 된다.) 이 경우 부모 클래스의 동작이 변경되면 자식 클래스들의 동작도 모두 영향을 받게 된다.

 

두 클래스의 관계가 'IS-A' 관계인 경우 이런 변경은 자연스럽다. 하지만 일반적인 경우 두 클래스 사이에 불필요한 종속성(Dependencies)이 생기는 것을 옳지 못하다. 따라서 무분별하게 상속을 남발하는 경우는 피해야한다.

 

클래스의 상속과 위임을 잘 알고 사용하자.

반응형

댓글