[OOP] 상속(Inheritance)이란?

calm0_0·2023년 9월 6일
0

OOP

목록 보기
2/6

상속(Inheritance)이란?


상속(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

profile
공부한 내용들을 정리하는 블로그

0개의 댓글