상속의 개념
상속의 정의
- 객체지향의 가장 큰 특징 가운데 하나가 재사용성의 향상이다. 객체지향 기술이 도입되게 된 이유이기도 함.
- 객체지향에서 이러한 재사용성을 향상시키기 위해 등장한 개념이 상속(Inheritance)이다.
상속은 동일한 데이터나 함수의 중복 정의를 피하고 공통된 데이터나 함수를 함 곳에 정의하여 재사용하는 개념이다.
클래스들로부터 공통된 속성과 함숟르을 추출하여 이들이 갖는 새로운 클래스를 정의할 수 있도록 하는 기법.
down-top 방식의 의한 상속이라 하며, 일반화(Generalization)
특정 클래스로부터 세부적인 여러 형태의 클래스들로 분류하여 상속을 표현.
top-down에 의한 상속이라 하며, 특수화(Specialization)
둘다 상속을 지칭하는 것으로서 상속관계를 표현하는 접근 방식의 차이만 있을 뿐이다.
클래스와 클래스 간의 관계이다.
상속에서 공통된 데이터 함수가 정의된 클래스를 슈퍼클래스(베이스 클래스, 부모클래스)
공통된 내용들을 그대로 재사용하면서 각자 한정적인 데이터나 함수들을 갖고 있는 클래스를 서브클래스(파생클래스, 자식클래스)
상속으로 인해 슈퍼 클래스에 정의된 데이터와 함수들을 중복 정의하지 않고 그대로 재사용할 수 있다.
상속을 is - A 관계이다.
서브 클래스 is a 슈퍼클래스
서브 클래스이면서 슈퍼클래스이다.(서브 클래스 = 슈퍼클래스) 라는 의미를 나타낸다.
반대로 슈퍼클래스 is a 서브 클래스 관계는 해당하지 않는다.
is - a 관계를 객체지향 프로그래밍 언어에서는 "upcasting" 이라는 메커니즘으로 표현.
upcasting을 통해 상속에서 제공하는 재사용성 이외에 "대체성(Substitutability)"라는 특징을 제공한다.
대체성은 상속 관계에서 슈퍼 클래스의 객체 대신에 서브클래스의 객체가 대신 대체되어 사용될 수 있다는 것이다.
예) 결제라는 슈퍼클래스의 객체가 사용될 자리에 슈퍼클래스 객체 대신 서브 클래스인 CreditCard, Cash, Point 등의 객체들이 대신 사용할수 있다.
public class Paymanet {
public void processPayment(Payment p) {
p.pay();
}
}
public class CreditCard extends Payment {
String cardNum;
String expireDate;
public void pay() {
//신용카드 결제 로직
}
}
public class Cash extends Payment {
String account;
String bankName;
public void pay() {
//현금이체
}
}
public class Point extends Payment {
int point;
public void pay() {
//포인트 결제
}
}
상속관계에서는 슈퍼 클래스가 하나가 아닌 둘 이상 존재 가능하다.
이러한 경우 다중 상속이라고 한다.
다중 상속의 경우 슈퍼클래스가 복수개 있기 때문에 상속받는 데이터나 함수의 개수가 더 많게 된다.
그러나 다중 상속을 사용하는 경우에 있어서 문제점이 발생할 수 있다. 그것은 바로 '이름 충돌(Naming Confliction)'이다.
상속받는 슈퍼클래스 내에 동일한 이름의 데이터나 함수가 존재할 경우, 상속받는 서브클래스에서는 양쪽에서 모두 상속을 받기 때문에 해당 데이터나 함수를 사용할 경우 어느 부모 클래스의 데이터 또는 함수인지 충돌이 발생한다.
이를 피하기 위해서 Java 언어에서는 클래스 간의 다중 상속을 허용하고 있지 않다.
우회적으로 다중 상속을 실현하기 위해 상속은 하나의 슈퍼클래스로 받고, 다른 하나는 인터페이스로 구현하는 형태를 취한다.
public class A {
int a;
public void f1() {}
}
interface B {
public void f1() {}
}
public class B extends A, implements B {
public void f3() { super.f1(); } //슈퍼클래스 A의 f1()를 상속받음
public void f1() { ... } // interface B의 f1()을 구현함
}
상속의 특성
1. 데이터와 함수의 중복성을 제거한다.
- 클래스들 간의 관계가 상속관계에 있으면 클래스들 사이에는 중복된 데이터나 함수들이 존재하지 않게 된다.
물론 예외적으로 서브 클래스에서 슈퍼클래스의 데이터나 함수를 상속받지 않고 재정의 할 수 있다.
그러나 일반적으로 슈퍼 클래스에 정의된 데이터나 함수를 서브 클래스에 정의하지 않아도 그대로 재사용할 수 있기 때문에 기존의 절차적 프로그래밍의 기범에 비해 중복성이 많이 감소한다.
2. 데이터나 함수의 추가가 용이하다.
- 상속관계 있는 서브 클래스는 슈퍼클래스의 데이터와 함수를 상속받는다는 측면에서는 슈퍼클래스에 의존적이지만, 서브클래스 자체로서 독립적인 단위이기 때문에 서브클래스에 데이터나 함수를 새롭게 추가하는 것이 쉽게 이루어질 수 있다.
서브클래스에 데이터나 함수를 추가하는 것이 상속받는 슈퍼클래스에 영향을 주지 않는다.
예) 상품 클래스의 하위 클래스인 TV등에서 필요한 데이터나 함수를 자유롭게 정의할 수 있다.
3. 새로운 클래스의 추가가 용이하다.
- 새로운 하위 클래스의 추가가 용이하다.
그리고 추가 되는 클래스는 자신의 슈퍼클래스 개수 만큼 해당 클래스에 정의된 데이터나 함수를 상속받는다.
예) 상품클래스 밑에 새로운 하위 클래스 냉장고나 에어콘등을 쉽게 추가할 수 있다.
정리
- 상속은 데이터나 함수의 재사용을 위한 장치이다.
- 상속은 is - a 관계이다.
- 다중 상속은 슈퍼클래스가 둘 이상 존재하는 것이다.
- 상속을 이용하면 데이터와 함수의 중복성을 제거한다.
- 상속을 이용하면 데이터나 함수의 추가가 용이하다.
- 상속을 이용하면 새로운 클래스의 추가가 용이하다.
- 상속을 이용하면 슈퍼클래스가 복수개 존재할 수 있다.
- 자바 언에서는 "extends"를 이용해서 상속구조를 구현하는데, 클래스 간의 다중 상속을 허용하지 않는다.
출처-UML과 JAVA로 배우는 객체지향 설계 및 구현