설계할 때 상속은 언제 사용?

hyHA·2023년 11월 12일
0
post-thumbnail
post-custom-banner

프로그래밍할 때 상속을 사용하는 이유는 하나의 카테고리 안에서 재사용확장을 하기 위함이다
즉, is a kind of 관계에서 사용한다

계층도가 아닌 분류도

상속이라고 하면 아래와 같은 구조를 생각하기 쉽지만,

오히려 아래와 같이 이해하는게 상속을 더 제대로 이해할 수 있다.
상속은 조직도나 계층도가 아닌 분류도이다!

하위 클래스는 상위 클래스이다

상속 관계에서 아주 중요한 문장이 있다
이 문장은 객체 지향 설계 5원칙 가운데 LSP(리스코프 치환 원칙)을 나타내는 말이다.

  • 하위 클래스는 상위 클래스다.

조직도의 경우에는 이 문장이 성립이 안된다

  • 아버지는 할아버지다.

하지만 분류도는 성립된다

  • 고래는 포유류다.

아래의 경우에서 어떤 것이 말이 되는지 보면 더 확실하게 알 수 있다

동물 푸바오 = new 판다(); // 판다를 낳고, 동물 역할을 하는 푸바오라 이름 지음(말이 됨)
아버지 영희아빠 = new 딸(); //딸을 낳고, 아버지 역할을 하는 영희아빠라 이름 지음(이상..)

is a kind of

흔히 상속은 is a 관계라고 하지만 이보다는 is a kind of이 좀더 정확한 표현이다
즉, 상속은 "분류"를 나타내는 관계를 가진다.

  • 판다 is a 동물 -> 판다는 동물이다(완벽히 맞다고 하기 어렵다. 동등 관계가 아니기 때문이다)
  • 판다 is a kind of 동물 -> 판다는 동물의 한 분류다(좀더 정확한 표현이다)

다중 상속을 지원하지 않는 이유

아래 그림을 보면 다중 상속의 문제점이 보인다.
물고기도 수영할 수 있고, 사람도 수영할 수 있을 때, 인어는 어떻게 수영해야 할까?
이 같은 문제를 다중 상속의 다이아몬드 문제라고 한다.
결국 다중 상속은 득보다 실이 더 많았기에 자바는 다중 상속을 포기하고 인터페이스를 도입했다.

인터페이스는 be able to

상속을 더 잘 이해하려면 인터페이스와 비교하면 좋다

자바는 다중 상속을 포기하고 인터페이스를 도입했다.
그럼 인터페이스는 어떤 관계를 나타낼까?

아래 그림을 통해 알 수 있듯이 인터페이스는 "무엇을 할 수 있는" 관계를 나타낸다.

상속과 UML표기법

상속과 인터페이스의 UML표기법은 아래와 같다

UML을 더 자세히 알고 싶다면 로버트 C.마틴의 [UML 실전에서는 이것만 쓴다]와 마틴 파울러의 [UML Distilled 2판]을 보자

상속과 T 메모리

public class Animal{
	public String name;
    
    public void showName(){
    	System.out.printf("안녕 나는 %s야. 반가워\n", name);
    }
}
---
public class Panda extends Animal {
	public String habitat;
    
    public void showName(){
    	System.out.printf("%s는 %s에 살아\n", name, habitat);
    }
}
---
public class Driver {
	public static void main(String[] args){
    
    	Penguin pororo = new Penguin(); //Penguin 객체(pororo) 생성 
        
        pororo.name = "뽀로로";
        pororo.habitat = "남극";
        
        pororo.showName();
        pororo.showHanitat();
        
        Animal pingu = new Penguin(); //Animal 객체(pingu) 생성
        
        pingu.name = "핑구";
        //pingu.habitat = "EBS";
        
        pingu.showName();
        //pingu.showHabitat();
        
        //Penguin happyfeet = new Animal();
    }
}

pororo가 생성될 때의 T 메모리 구조를 보면 아래와 같다
Penguin 클래스의 인스턴스만 힙 영역에 생긴것 뿐만 아니라 Animal 클래스의 인스턴스도 함께 힙 영역에 생겼다!
하위 클래스의 인스턴스가 생성될 때 상위 클래스의 인스턴스도 함께 생성된다는 것이다.
사실 이때 모든 클래스의 최상위 클래스인 Object 클래스의 인스턴스도 함께 생성된다

pingu가 생성될 때의 T 메모리 구조를 보면 아래와 같다
pingu객체 참조 변수가 가리키고 있는 것은 Penguin 인스턴스가 아닌 Animal 인스턴스다
따라서 pingu객체는 showHabitat()메서드를 사용할 수 없다

class Animal{}
class Cat extends Animal {} // Cat이 Animal을 상속
---
// Cat 클래스로부터 Cat 객체를 생성
// Cat 객체를 Animal 변수에 대입하여 자동 타입 변환이 일어남. 
Animal animal = new Cat(); 

// 위와 아래는 같은 의미
Cat cat = new Cat();
Animal animal = cat;

참고
스프링 입문을 위한 자바 객체 지향의 원리와 이해

profile
룰루랄라
post-custom-banner

0개의 댓글