이번 글에서는 객체 지향 프로그래밍(Object-Oriented Programming, OOP)의 핵심 요소 중 하나인 '오버라이딩(Overriding)'에 대해 상세하게 다루겠습니다. 이전에는 객체 확인 연산자와 그 활용법에 대해 살펴봤지만, 이번 글에서는 오버라이딩을 어떻게 활용하는지, 그리고 왜 필요한지 등에 대해 심화된 내용과 실제 사례를 통해 설명하겠습니다.
1. 오버라이딩(Overriding)이란?
객체 지향 프로그래밍에서 '오버라이딩'은 상속 관계에 있는 클래스 간 메소드를 재정의하는 것을 말합니다. 자식 클래스에서 부모 클래스의 메소드를 동일한 이름으로 재정의하면, 부모 클래스의 메소드 대신 자식 클래스의 메소드가 호출됩니다. 이 기능은 다형성(Polymorphism)을 구현하는 데 있어 핵심적인 역할을 합니다.
2. 왜 오버라이딩을 사용하는가?
다형성은 OOP에서 중요한 개념 중 하나입니다. 같은 타입(부모 클래스)로 여러 객체(자식 클래스 인스턴스)를 참조할 때 각각 다른 동작을 수행하기 위해서는 오버라이딩 기법을 사용합니다.
예를 들어, Animal 타입으로 Dog와 Cat 인스턴스를 참조한다고 가정합시다. 모든 동물들은 소리를 낼 수 있지만 (sound() 메서드), 각 동물마다 내는 소리는 서로 다릅니다. 이런 경우 Dog와 Cat클래스에서 sound()메서드를 오버라이딩하여 고유한 소리(bark(), meow())를 출력하도록 할 수 있습니다.
3. 오버라이딩 활용
Java 언어 기준으로 Animal 클래스가 있고 Dog 클래스와 Cat 클래스가 Animal 클래스를 상속받았다고 가정하겠습니다.
예시 코드:
public class Animal {
public void sound() {
System.out.println("The animal makes a sound");
}
}
public class Dog extends Animal {
@Override
public void sound() {
System.out.println("The dog barks");
}
}
public class Cat extends Animal {
@Override
public void sound() {
System.out.println("The cat meows");
}
}
위 예제에서 Dog와 Cat클래스는 모두 Animal클래스로부터 sound()메소드를 상속받았으며 각각 재정의(오버라이딩)하여 고유한 소리를 출력하도록 했습니다.
4. 오버라이딩 예시
Animal myAnimal = new Dog();
myAnimal.sound(); // Outputs: "The dog barks"
myAnimal = new Cat();
myAnimal.sound(); // Outputs: "The cat meows"
위 코드는 오버라이딩의 예시입니다. Animal 타입의 변수 myAnimal에 Dog 객체와 Cat 객체를 할당한 후, sound() 메소드를 호출하면 각각 다른 결과가 출력됩니다.
5. 주의사항
오버라이딩은 유용하지만, 잘못 사용하면 예상치 못한 결과를 초래할 수 있습니다. 메소드를 오버라이드할 때는 항상 @Override 어노테이션을 사용하여 컴파일러에게 이 메소드가 부모 클래스의 메소드를 오버라이딩하는 것임을 명시적으로 알려주는 것이 좋습니다.
또한, 자식 클래스에서 부모 클래스의 메서드를 오버라이딩 할 때에는 접근 제어자(access modifier)에 주의해야 합니다. Private 메소드는 오버라이딩할 수 없습니다. 그리고 protected나 default 접근 제어자로 선언된 부모 클래스의 메소드를 자식 클래스에서 public으로 오버라이딩하는 것은 가능하지만, 반대의 경우는 허용되지 않습니다. 즉, 접근 범위를 축소하는 오버라이딩은 허용되지 않습니다.
6. 활용 사례
오버라이딩은 다양한 상황에서 유용하게 사용됩니다.
- 게임 개발: 게임 내의 다양한 캐릭터들이 같은 타입(예: Character)을 공유하지만 각각 고유한 동작(예: attack())을 수행해야 할 때, 이러한 동작들을 오버라이딩하여 구현할 수 있습니다.
- GUI 프로그래밍: 여러 컴포넌트(Button, TextField 등)가 같은 이벤트 리스너 인터페이스(ActionListener 등)를 구현하면서 각각 다른 동작을 수행해야 할 때, 이벤트 처리 메서드를 오버라이딩하여 구현합니다.
7. 결론
객체 지향 프로그래밍에서 '오버라이딩'은 중요한 개념입니다. 이 개념을 이해하고 활용하면 코드의 유연성과 확장성을 높일 수 있으며, 복잡한 문제에 대응하는데 유용합니다.
그러나 이런 기능들도 잘못 사용되면 예상치 못한 결과를 초래할 수 있으므로 주의가 필요합니다. 특히 메소드 시그니처와 접근 제어자에 대해 충분히 숙지하고 올바르게 사용하는 것이 중요합니다.
'Programming > 객체 지향 프로그래밍(OOP)' 카테고리의 다른 글
OOP 활용: 인터페이스(Interface) (1) | 2023.10.07 |
---|---|
OOP 활용: 추상클래스(Abstract Class) (0) | 2023.10.06 |
OOP 활용: 객체 확인 연산자(다형성) (0) | 2023.10.04 |
OOP 활용: 다운캐스팅(다형성) (0) | 2023.10.03 |
OOP 활용: 업캐스팅(다형성) (0) | 2023.10.02 |