상속(Inheritance)이란 객체지향의 특징 중 하나로 부모 클래스의 속성과 메서드를 자식 클래스가 물려받는 것을 말한다.
상속을 받은 자식 클래스는 부모 클래스와 다른 부분만 추가하거나 재정의함으로써 기존 코드를 쉽게 확장할 수 있다.
다음 예제에서는 자동차와 오토바이 객체를 코드로 표현했다.
public class Car {
String model;
String color;
int wheels;
// Car 클래스 고유의 속성
boolean isConvertible;
void moveForward() {
System.out.println("앞으로 전진합니다.");
}
void moveBackward() {
System.out.println("뒤로 후진합니다.");
}
// Car 클래스 고유의 기능
void openWindow() {
System.out.println("모든 창문을 엽니다.");
}
}
public class MotorBike {
String model;
String color;
int wheels;
// MotorBike 클래스 고유의 속성
boolean isRaceable;
void moveForward() {
System.out.println("앞으로 전진합니다.");
}
void moveBackward() {
System.out.println("뒤로 후진합니다.");
}
// MotorBike 클래스 고유의 기능
void stunt() {
System.out.println("오토바이로 묘기를 부립니다.");
}
}
위 예제에서는 보면 여러 코드가 중복되고 있다. model, color, wheels, moveForward(), moveBackward()은 두 클래스의 동일한 속성과 기능들로 똑같은 코드가 반복되는 문제점이 있다. 이렇게 중복된 부분에 변경 사항이 생기면 해당 변경 사항을 다른 클래스에서도 일일이 수정해주어야 하는 어려움이 있다.
이를 추상화와 상속을 활용하여 다음과 같이 바꿔보았다.
public class Vehicle { // 추상화를 통한 상위 클래스 정의
String model;
String color;
int wheels;
void moveForward() {
System.out.println("전진합니다.");
}
void moveBackward() {
System.out.println("후진합니다.");
}
}
public class Car extends Vehicle {
boolean isConverible;
void openWindow() {
System.out.pritln("모든 창문을 엽니다.");
}
}
public class MotorBike extends Vehicle {
boolean isRaceable;
// 메서드 오버라이딩을 활용한 기능 재정의
@Override
void moveForward() {
System.out.println("오토바이가 앞으로 전진합니다.");
}
void stunt() {
System.out.pritln("오토바이로 묘기를 부립니다.");
}
}
public class Main {
public static void main(String[] args) {
Car car = new Car();
MotorBike motorBike = new MotorBike();
car.model = "테슬라";
car.color = "빨강색";
System.out.println("나의 나동차는 " + car.color + " " + car.model + "입니다.");
car.moveForward();
motorBike.moveForward();
motorBike.moveBackward();
}
}
// 출력
// 나의 나동차는 빨강색 테슬라입니다.
// 전진합니다.
// 오토바이가 앞으로 전진합니다.
// 후진합니다.
바뀐 예제에서는 Car와 MotorBike 클래스의 공통적인 속성과 기능들을 추출하여 Vehicle 이라는 상위 클래스를 정의하였다. 그리고 이를 Car, MotorBike 클래스에어 상속 받아 상위 클래스(Vehicle)의 속성과 기능들을 사용하도록 했다.
이로 인해 더 이상 중복되는 속성과 기능들을 반복적으로 정의하지 않아도 된다. 또한, 상위 클래스에서 단 한번의 수정으로 이를 상속 받는 모든 하위 클래스에 변경 사항이 반영된다.
상속 받는 하위 클래스는 상위 클래스의 속성과 기능들을 그대로 사용할 수도 있지만 MotorBike 클래스처럼 각 클래스에 맞게 메서드 오버라이딩을 사용하여 해당 내용을 재정의할 수도 있다.
그렇다면 상속을 사용하면서 얻을 수 있는 이점은 무엇이 있을까? 상속을 사용함으로써 얻을 수 있는 효과에는 다음과 같은 것들이 있다.
상속을 지나치게 많이 사용할 때의 문제점으로는 다음과 같은 것들이 있다.
(이러한 상속의 문제점은 위임(Delegation)으로 해결할 수 있는데 이에 대해서는 다음 시간에 다뤄보려고 한다.)
Reference
한 번 읽으면 두 번 깨닫는 객체지향 프로그래밍
https://www.codestates.com/blog/content/%EA%B0%9D%EC%B2%B4-%EC%A7%80%ED%96%A5-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%ED%8A%B9%EC%A7%95