티스토리 뷰
기존의 클래스를 재사용하는 것이다. 적은 양의 코드로 새로운 클래스를 구현할 수 있고, 공통된 코드를 수정하는데에도 용이한 기법이다.
만약 사람이라는 클래스와 학생이라는 클래스를 정의한다고 했을때, 학생이라는 클래스는 사람이라는 공통된 성질을 가지면서, 학생이라는 특수한 성질을 가질 수 있다. 따라서 학생 클래스를 정의한다고 할때, 사람이라는 클래스를 상속받아서 공통된 특성을 포함시키고, 학생의 특수한 부분은 따로 만들어낼 수 있다는 것이다.
아래 코드를 통해 자세히 알아보도록 하자.
// 사람
class Person {
int age; // 나이
String name; // 이름
// 먹는다
void eat() {}
}
// 학생
class Student extends Person {
int studentNumber; // 학번
// 공부한다
void study() {}
}
위 코드는 학생 클래스가 사람 클래스의 상속을 받는 것을 표현한 것이다.
사람은 나이와 이름이 있고 먹는 행위를한다.
학생은 나이와 이름, 학번이 있고 먹는 행위와 공부하는 행위를 할 수 있다.
여기서 상속을 하는 클래스(Person)는 부모 클래스라고 부른다. 그리고 상속을 받는 클래스(Student)는 자식 클래스라고 부른다.
자식 클래스는 부모 클래스의 모든 멤버변수와 메소드들을 포함한다. 따라서 자식 클래스는 부모 클래스의 모든 특성을 안고가면서 자식 클래스의 특성을 따로 구현하는 것이다.
상속의 목적
그렇다면 상속을 하는 목적은 무엇일까? 위의 학생 클래스를 사람 클래스의 상속을 받지 않고 구현하는 것이 가능하다. 하지만 우리는 상속을 사용해야하는 중요한 이유가 있다.
1. 코드의 중복을 최소화할 수 있다.
// 사람
class Person {
int age; // 나이
String name; // 이름
// 먹는다
void eat() {}
}
// 학생
class Student {
int age; // 나이
String name; // 이름
int studentNumber; // 학번
// 먹는다
void eat() {}
// 공부한다
void study() {}
}
만약에 상속을 사용하지 않고 클래스를 생성했다면 위와 같이 구현해야할 것이다. 사람이라는 특성이 학생에도 존재하지만 학생 클래스를 생성하려면 사람의 특성까지 일일이 구현해 줘야 한다는 것이다. 그래서 같은 코드를 중복하여 작성하는 일이 벌어진다. 상속을 이용하면 이러한 중복을 없애줄 수 있다.
2. 프로그램의 생산성과 유지보수에 큰 도움을 줄 수 있다.
// 사람
class Person {
int age; // 나이
String name; // 이름
// 먹는다
void eat() {}
}
// 학생
class Student extends Person {
int studentNumber; // 학번
// 공부한다
void study() {}
}
// 선생님
class Teacher extends Person {
// 가르친다
void teach() {}
}
// 운동선수
class Athlete extends Person {
// 달린다
void run() {}
}
위와 같은 상황이 있다고 하자. 학생, 선생님, 운동선수 클래스는 사람 클래스의 상속을 받는다. 만약 사람 클래스에 sleep이라는 메소드를 추가한다면 사람 클래스를 상속받은 모든 클래스는 sleep을 사용할 수 있게 된다.
만약에 Person을 상속받지 않았을 경우에는 어떻게 될까? 각 클래스마다 sleep이라는 메소드를 일일이 넣어줘야 한다. 위 예제에서는 클래스 세개만 수정하면 되므로 별로 수고스럽지 않은 작업처럼 보일 수 있지만, 상속 받는 클래스가 많아지면 이 작업은 정말 비효율적이게 될 것이다.
결국 개발 속도가 빨라져 '생산성'의 증가로 이어지게 되며, 코드를 수정함에 있어서 효율적이게 되어 '유지보수성'이 증가되는 결과를 얻을 수 있다.
포함관계 vs 상속관계
우리가 클래스를 정의할 때 그 클래스들의 관계를 정확히 알고 코딩할 필요가 있다. 클래스들은 대체적으로 아래의 두 관계를 보인다.
상속관계 = is-a 관계(B는 A이다.)
포함관계 = has-a 관계(A는 B를 가지고 있다.)
상속관계는 is-a관계라고 할 수 있다. 위 그림에서 볼 수 있듯이 is-a는 'B is a A'라는 말이 성립해야 한다.
실제 예시로 설명하자면, 위에서 보았듯이 '학생은 사람이다.'라는 관계가 어색하지 않다. 이러한 경우 학생은 사람의 특성을 가지고 있다고 할 수 있다. 이런 관계를 상속관계로 정의할 수 있다.
포함관계는 has-a관계라고 할 수 있다. 이 관계를 성립하기 위해서는 'A has a B'라는 말이 성립해야 한다. 위 그림과 같이 B가 A에 포함되어 여러 구성체 중에 하나일 경우를 말한다.
실제 예시로 들어보면, 얼굴이라는 클래스가 있다면, 그 안에 눈, 코, 입이 포함되어 있다. 여기서 '얼굴은 눈, 코, 입을 가지고있다.'라고 할 수 있다. 따라서 어떤 클래스가 다른 클래스를 포함하는 관계라고 할 수 있다.
상속관계와 포함관계를 확실하게 알 수 없다면 위의 is-a관계과 has-a관계를 생각해보면 수월할 수 있다.
참고
java의 정석 - 남궁성
'Programming > Java' 카테고리의 다른 글
[Java]예외(Exception) (0) | 2018.07.11 |
---|---|
[Java]Class Design(Class & Abstract Class & Interface) (1) | 2018.07.11 |
[Java]환경변수(JAVA_HOME & CLASSPATH) (5) | 2018.07.04 |
[Java]Call by value & Call by reference (1) | 2018.07.02 |
[Java]JVM 메모리 구조(JVM Memory Structure) (6) | 2018.06.26 |