개발하는 자몽

[객체 지향] is-a, has-a 본문

Java & Kotlin

[객체 지향] is-a, has-a

jaamong 2022. 7. 16. 09:51

상속을 공부하다가 is-a, has-a 관계를 명확하게 알아둬야 사용에 유의할 수 있음을 깨달았다.

 

is-a

간단히 is-a는 'A는 B이다''~이다'와 같다. 

is-a는 추상화(형식이나 클래스와 같은)들 사이의 포함 관계를 의미한다. 한 클래스 A가 다른 클래스 B의 서브클래스임을 말한다. 타입 A는 타입 B의 명세(specfication)를 암시한다는 점에서 타입 B의 서브타입이라고도 할 수 있다.

is-a 관계는 타입 또는 클래스 간의 has-a 관계와는 대조된다. has-a 및 is-a 관계들 간의 혼동은 실세계 관계 모델에 대한 설계에 있어 자주 발견되는 에러이다. 또한 객체 또는 타입 간의 instance-of 관계와도 대조된다.

- 위키피디아 -

is-a 관계를 통해 생성된 클래스 및 객체는 상속 관계에서 둘은 밀접하게 결합되므로 부모 클래스의 명세에 변경이 발생하면 코드가 손상될 위험이 있다. 하지만 이러한 밀접한 관계는 클래스 계층구조에서 좀 더 안정적인 기반을 마련한다는 의미이기도 하다. 또한 상위 클래스의 기능을 하위 클래스가 물려받아 사용할 수 있는 장점도 있다.

 

상속의 경우 is 관계가 확실한 경우 사용하자.

  • 강아지, 사자, 독수리는 동물이다.
  • 스파크, K5는 자동차이다.
package inheritance;

class Animal {
    public void move() {
        System.out.println("동물이 움직인다.");
    }
}

class Cat extends Animal {
    public void move() {
        System.out.println("고양이가 네발로 걷는다.");
    }
}

class Eagle extends Animal {
    public void move() {
        System.out.println("독수리가 하늘을 난다.");
    }
}

is-a 관계가 확실하여 상속을 하는 경우, 서브 클래스에서 다형성을 가질 수 있다. (위 코드는 is-a 관계인 경우 상속하는 방법만 보여주고 있다.)

주의할 점은 상속은 코드 재사용을 위해 사용하는 것이 아니다. 코드를 재사용할 수 있지만 이를 위한 방법이 아니다. 상속은 하위 클래스가 상위 클래스의 기능을 상속받으면서 추가적으로 더 많은 기능과 특성을 갖기 위해 사용한다(다형성). 일반적(상위 클래스)이고 구체적(하위 클래스)인 관계(is-a)인 경우 사용한다는 뜻이다.

 

 

has-a

has-a는 구성 관계를 의미한다. 한 오브젝트(구성된 객체, 또는 부분/멤버 객체라고도 부른다)가 다른 오브젝트(composite type)에 "속한다(belongs to)"를 말한다. 단순히 말해, has-a 관계는 객체의 멤버 필드라고 불리는 객체를 말하며, Multiple has-a 관계는 소유 계층구조를 형성하기 위해 결합하는 경우를 말한다.

- 위키피디아 -

 

has-s 관계는 원과 점으로 보여줄 수 있다. 

package inheritance;

public class Point {
    private int x;
    private int y;

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }
}
package inheritance;

public class Circle {

    //Point class가 x, y를 갖고 있지만 원(Circle)과 점(Point)은 상속관계가 아님
    //상속처럼 일반적이고 구체적인 관계(is-a 관계)가 아닌, Circle class에서 Point의 점(x, y)를 활용하고 싶은 것
    //이럴 때는 상속이 아니다 -> 합성(has-a 관계)

    Point point; //합성
    private int radius;

    public Circle() {
        point = new Point();
    }
}

Circle 클래스의 기능 구현을 위해 Point 클래스를 갖고 있다(has-a 관계).

 

 

is-a, has-a 관계를 명확히 학습하고 상속을 할 때 유의하도록 하자.

 

 

 

 

참고

 

객체 지향적 관점에서의 has-a와 is-a 차이점

객체 지향의 꽃이라고도 할 수 있는 객체들 간의 '관계'는 설계에 있어서 중요하다고 할 수 있습니다. 객체 간의 관계를 정의하는 키(key)라고도 볼 수 있습니다. 이 포스팅에서 is-a 와 has-a에 대해

minusi.tistory.com

Comments