메소드 오버라이딩

섬네일|메소드 오버라이딩 그림.
**메소드 오버라이딩**(method overriding)은 객체 지향 프로그래밍에서 서브클래스 또는 자식 클래스가 자신의 슈퍼클래스들 또는 부모 클래스들 중 하나에 의해 이미 제공된 메소드를 특정한 형태로 구현하는 것을 제공하는 언어의 특징이다. 서브클래스에서의 구현은 부모 클래스에서 같은 이름, 같은 파라미터 또는 시그니처 그리고 같은 반환형을 갖는 메소드를 제공함으로써 슈퍼클래스에서의 구현을 오버라이드한다. 실행되는 메소드의 버전은 이것을 발생시키는데 사용되는 객체에 의해서 결정될 것이다. 만약 부모 클래스의 객체가 메소드를 발생시키는데 사용된다면 부모 클래스 버전이 실행될 것이지만, 만약 서브클래스의 객체가 메소드를 발생시키는데 사용된다면 자식 클래스 버전이 실행될 것이다. 몇몇 언어들은 프로그래머가 메소드를 오버라이딩하는 것을 예방하게할 수 있게 한다.

## 언어별 예시
### C++
C++에서, 부모 또는 기본 클래스의 이름은 함수들을 오버라이드하기 위한 범위 지정 연산자(scope resolution operator) 이후에 사용된다. 예를 들면 다음의 코드는 두 클래스들을 나타내는데, 기본 클래스 `TRectangle`, 그리고 유도 클래스 `TBox`이 그것이다. `TBox`는 `TRectangle` 클래스의 `print()` 메소드를 오버라이드하며, 또한 자신의 높이를 보여준다.
```cpp
#include <iostream>

//---------------------------------------------------------------------------
class TRectangle
{
public:
    TRectangle(double l, double w) : length(l), width(w) {}
    virtual void print() const;

private:
    double length;
    double width;
};

//---------------------------------------------------------------------------
void TRectangle::print() const
{
   // print() method of base class.
   std::cout << "Length = " << this->length << "; Width = " << this->width;
}

//---------------------------------------------------------------------------
class TBox : public TRectangle
{
public:
    TBox(double l, double w, double h) : TRectangle(l, w), height(h) {}
    // virtual is optional here, but it is a good practice to remind it to the developer.
    virtual void print() const;
private:
    double height;
};

//---------------------------------------------------------------------------
// print() method of derived class.
void TBox::print() const
{
   // Invoke parent print() method.
   TRectangle::print();
   std::cout << "; Height = " << this->height;
}
```
클래스 `TBox`에서 `print()`는 메소드 `print()`의 부모 버전을 불러일으킴으로써, 또한 기본 클래스의 private 변수 `length`와 `width`를 출력할 수 있다. 반면, 이러한 변수들은 `TBox`에 접근할 수 없다.

다음 구문은 타입 `TRectangle` 와 `TBox`,의 객체들을 인스턴스화할 것이며, 그들 각각의 `print()` 메소드들을 호출한다:
```cpp
int main(int argc, char** argv)
{
   TRectangle rectangle(5.0, 3.0);

   // Outputs: Length = 5.0; Width = 3.0
   rectangle.print();

   TBox box(6.0, 5.0, 4.0);

   // The pointer to the most overridden method in the vtable in on TBox::print,
   // but this call does not illustrate overriding.
   box.print();

   // This call illustrates overriding.
   // outputs: Length = 6.0; Width = 5.0; Height= 4.0
   static_cast<TRectangle&>(box).print();
}
```
C++11에서는 자바와 비슷하게 슈퍼클래스에서 `final`로 정의된 메소드는 오버라이딩될 수 없다; 또한 메소드는 컴파일러가 기본 클래스에서 메소드를 오버라이드하는지를 검사하기 위해 `override`가 선언될 수 있다.

### 델파이
델파이에서 메소드 오버라이딩은 지시자 **override**를 통해 수행되지만, 단지 메소드가 **dynamic** 또는 **virtual** 지시자로 표시되어야 한다.

**inherited**라는 단어는 슈퍼클래스 행동을 호출하기를 원할 때 반드시 호출되어야 한다.
```pascal
type
  TRectangle = class
  private
    FLength: Double;
    FWidth: Double;
  public
    property Length read FLength write FLength;
    property Width read FWidth write FWidth;

    procedure Print; virtual;
  end;

  TBox = class(TRectangle)
  public
    procedure Print; override;
  end;
```


### 파이썬
파이썬에서, 서브클래스는 슈퍼클래스의 메소드를 오버라이드하는 메소드를 포함하며, 또한 `self.method.In`  대신 super(Subclass, self).method를 호출함으로써 슈퍼클래스를 호출할 수 있다.
```python
class Thought(object):
    def __init__(self):
        pass
    def message(self):
        print "I feel like I am diagonally parked in a parallel universe."

class Advice(Thought):
    def __init__(self):
        super(Advice, self).__init__()
    def message(self):
        print "Warning: Dates in calendar are closer than they appear"
        super(Advice, self).message()
```


### 루비
루비에서, 서브클래스는 슈퍼클래스의 메소드를 오버라이드하는 메소드를 포함하며, 또한 오버라이딩 된 메소드에서 super를 호출함으로써 슈퍼클래스를 호출할 수 있다. 만약 오버라이딩된 메소드 오버라이딩 메소드의 외부에서 보존되게 하고 싶다면 아래의 'super_message'와 함께 alias를 사용할 수 있다.
```ruby
class Thought
  def message
    puts "I feel like I am diagonally parked in a parallel universe."
  end
end

class Advice < Thought
  alias :super_message :message
  def message
    puts "Warning: Dates in calendar are closer than they appear"
    super
  end
end
```


### Java

```java
class Thought {
    public void message() {
        System.out.println("I feel like I am diagonally parked in a parallel universe.");
    }
}

public class Advice extends Thought {
    @Override  // @Override annotation in Java 5 is optional but helpful.
    public void message() {
        System.out.println("Warning: Dates in calendar are closer than they appear.");
    }
}
```


## 같이 보기
* 상속
* 함수 오버로드
* 다형성

## 각주
* Deitel, H. M & Deitel, P. J.(2001). *Java How to Program* (4th ed.). Upper Saddle River, NJ: Prentice Hall.
* Lewis, J. & Loftus, W. (2008). *Java: Software Solutions* (6th ed.). Boston, MA: Pearson Addison Wesley.
* Malik, D. S.(2006). *C++ Programming: Program Design Including Data Structure.* (3rd ed.). Washington, DC: Course Technology.
* Flanagan, David.(2002).*Java in a Nutshell.*Retrieved from http://oreilly.com/catalog/9780596002831/preview#preview 
* Meyer, Bertrand (2009). *Touch of Class: Learning to Program Well with Objects and Contracts*. Springer.

## 외부 링크
* Java Method Overriding by Hemanth Balaji
* Introduction to O.O.P. Concepts and More  by Nirosh L.w.C.
* Overriding and Hiding Methods by Sun Microsystems

분류:메소드 (컴퓨터 프로그래밍)