학습
Java 상속과 다형성
Java 상속과 다형성 — 중급
상속과 다형성
1. 도입 (왜 배워야 하는가)
상속과 다형성은 객체 지향 프로그래밍(OOP)의 핵심 개념으로, 코드를 재사용하고 프로그램의 유지보수성을 높이는 데 필수적입니다. 실무에서 객체 지향 프로그래밍을 사용하지 않으면 코드가 중복되고 복잡해져, 나중에 수정이나 확장이 어려워질 수 있습니다. 예를 들어, 쇼핑몰 시스템에서 다양한 제품을 관리할 때, 상속과 다형성을 활용하면 코드의 중복을 줄이고 관리하기 쉬운 구조로 만들 수 있습니다.
상속이 없다면, 모든 제품의 속성을 일일이 정의해야 하며, 다형성이 없다면 각 제품의 행동을 개별적으로 구현해야 합니다. 결과적으로 코드의 가독성이 떨어지고, 버그가 발생할 확률이 높아집니다.
2. 핵심 개념 설명
- 상속: 한 클래스가 다른 클래스의 속성과 메소드를 물려받는 개념입니다. 이를 통해 코드의 재사용성이 높아집니다.
- 다형성: 동일한 메소드가 다양한 방식으로 동작할 수 있는 능력입니다. 이를 통해 코드의 유연성을 높일 수 있습니다.
- 비유: 부모가 자녀에게 유전자를 물려주는 것과 같습니다. 자녀는 부모의 특성을 이어받습니다.
- 비유: 한 사람이 여러 역할을 수행하는 것과 같습니다. 같은 이름의 메소드가 객체의 종류에 따라 다르게 동작합니다.
| 용어 | 설명 |
|---|---|
| 상위 클래스 | 다른 클래스에서 상속받는 클래스 |
| 하위 클래스 | 상위 클래스를 상속받아 확장하는 클래스 |
| 오버라이딩 | 하위 클래스에서 상위 클래스의 메소드를 재정의하는 것 |
3. 기본 코드 예제
다음은 상속과 다형성을 보여주는 간단한 코드입니다.
class Animal {
void sound() {
System.out.println("동물이 소리를 냅니다.");
}
}
class Dog extends Animal {
@Override
void sound() {
System.out.println("멍멍");
}
}
class Cat extends Animal {
@Override
void sound() {
System.out.println("야옹");
}
}
public class Main {
public static void main(String[] args) {
Animal myDog = new Dog(); // Animal 타입의 Dog 객체 생성
Animal myCat = new Cat(); // Animal 타입의 Cat 객체 생성
myDog.sound(); // 멍멍 출력
myCat.sound(); // 야옹 출력
}
}
실행 결과
멍멍
야옹
코드 동작 설명
Animal클래스 정의: 기본적인 소리 메소드를 포함합니다.Dog클래스 정의:Animal클래스를 상속받고sound메소드를 오버라이드합니다.Cat클래스 정의:Animal클래스를 상속받고sound메소드를 오버라이드합니다.Main클래스에서Dog와Cat객체를Animal타입으로 생성합니다.- 각 객체에 대해
sound메소드를 호출하여 해당 클래스의 소리를 출력합니다. - 상속을 잘못 이해하기: 상속은 'is-a' 관계입니다. 예를 들어,
Dog는Animal의 한 종류이기 때문에 적절한 관계를 설정해야 합니다. - 오버라이드 시 메소드 시그니처 불일치: 하위 클래스에서 메소드를 오버라이드할 때, 반드시 메소드 시그니처가 일치해야 합니다.
- 상속과 다형성은 코드의 재사용성과 유지보수성을 높여줍니다.
- 상속은 부모 클래스의 속성과 메소드를 물려받는 개념입니다.
- 다형성은 동일한 메소드가 서로 다른 객체에서 다르게 동작하는 특성입니다.
- 다음에 학습하면 좋은 주제는 인터페이스와 추상 클래스입니다. 이러한 개념은 상속과 다형성을 더욱 깊이 이해하는 데 도움이 됩니다.
4. 실전 활용 예제
예제 1: 쇼핑몰 장바구니 구현
장바구니에는 여러 종류의 상품이 있을 수 있습니다. 상속과 다형성을 활용하여 다양한 상품을 정의할 수 있습니다.
abstract class Product {
String name;
double price;
Product(String name, double price) {
this.name = name;
this.price = price;
}
abstract void showInfo();
}
class Book extends Product {
Book(String name, double price) {
super(name, price);
}
@Override
void showInfo() {
System.out.println("책: " + name + ", 가격: " + price);
}
}
class Electronics extends Product {
Electronics(String name, double price) {
super(name, price);
}
@Override
void showInfo() {
System.out.println("전자기기: " + name + ", 가격: " + price);
}
}
public class ShoppingCart {
public static void main(String[] args) {
Product book = new Book("자바 프로그래밍", 25000);
Product phone = new Electronics("스마트폰", 800000);
book.showInfo(); // 책: 자바 프로그래밍, 가격: 25000 출력
phone.showInfo(); // 전자기기: 스마트폰, 가격: 800000 출력
}
}
예제 2: 동물원 관리 시스템
동물원에서 다양한 동물의 행동을 관리할 때도 상속과 다형성을 활용할 수 있습니다.
abstract class ZooAnimal {
abstract void feed();
}
class Lion extends ZooAnimal {
@Override
void feed() {
System.out.println("사자를 고기로 먹입니다.");
}
}
class Elephant extends ZooAnimal {
@Override
void feed() {
System.out.println("코끼리를 풀로 먹입니다.");
}
}
public class Zoo {
public static void main(String[] args) {
ZooAnimal lion = new Lion();
ZooAnimal elephant = new Elephant();
lion.feed(); // 사자를 고기로 먹입니다. 출력
elephant.feed(); // 코끼리를 풀로 먹입니다. 출력
}
}
5. 흔한 실수와 주의사항
- 잘못된 코드:
class Car extends Animal { // Car는 Animal이 아님
}
- 올바른 코드:
class Dog extends Animal {
}
- 잘못된 코드:
class Dog extends Animal {
void sound(int volume) { // 시그니처 불일치
}
}
- 올바른 코드:
class Dog extends Animal {
@Override
void sound() { // 메소드 시그니처 일치
}
}