프로그래밍할 때 상속을 사용하는 이유는 하나의 카테고리 안에서 재사용
과 확장
을 하기 위함이다
즉, is a kind of 관계
에서 사용한다
상속이라고 하면 아래와 같은 구조를 생각하기 쉽지만,
오히려 아래와 같이 이해하는게 상속을 더 제대로 이해할 수 있다.
상속은 조직도나 계층도가 아닌 분류도이다!
상속 관계에서 아주 중요한 문장이 있다
이 문장은 객체 지향 설계 5원칙 가운데 LSP(리스코프 치환 원칙)을 나타내는 말이다.
조직도의 경우에는 이 문장이 성립이 안된다
하지만 분류도는 성립된다
아래의 경우에서 어떤 것이 말이 되는지 보면 더 확실하게 알 수 있다
동물 푸바오 = new 판다(); // 판다를 낳고, 동물 역할을 하는 푸바오라 이름 지음(말이 됨)
아버지 영희아빠 = new 딸(); //딸을 낳고, 아버지 역할을 하는 영희아빠라 이름 지음(이상..)
흔히 상속은 is a 관계라고 하지만 이보다는 is a kind of이 좀더 정확한 표현이다
즉, 상속은 "분류"를 나타내는 관계를 가진다.
아래 그림을 보면 다중 상속의 문제점이 보인다.
물고기도 수영할 수 있고, 사람도 수영할 수 있을 때, 인어는 어떻게 수영해야 할까?
이 같은 문제를 다중 상속의 다이아몬드 문제라고 한다.
결국 다중 상속은 득보다 실이 더 많았기에 자바는 다중 상속을 포기하고 인터페이스를 도입했다.
상속을 더 잘 이해하려면 인터페이스와 비교하면 좋다
자바는 다중 상속을 포기하고 인터페이스를 도입했다.
그럼 인터페이스는 어떤 관계를 나타낼까?
아래 그림을 통해 알 수 있듯이 인터페이스는 "무엇을 할 수 있는" 관계를 나타낸다.
상속과 인터페이스의 UML표기법은 아래와 같다
UML을 더 자세히 알고 싶다면 로버트 C.마틴의 [UML 실전에서는 이것만 쓴다]와 마틴 파울러의 [UML Distilled 2판]을 보자
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;
참고
스프링 입문을 위한 자바 객체 지향의 원리와 이해