1. 다형성 - 오버라이드

 

 

  • 클래스 다이어그램에서 육군(Army), 해군(Navy), 공군(AirForce)은 Unit이라는 클래스를 통하여 공통 속성을 정의하고 있다.
  • 공통속성 : 이름(멤버변수 및 getter, setter), 공격(attack() 메서드)
  • 같은 이름이지만 다른 동작을 수행해야 하는 필요성
    → 모든 군대는 '공격'이라는 공통된 특성을 갖지만, 공격하는 방법은 육/해/공군이 서로 다르게 처리되어야 한다.
  • 부모 클래스가 갖고 있는 기능을 자식 클래스가 재정의
    → 부모 클래스에 정의된 것과 동일한 이름을 갖는 메서드를 자식 클래스가 정의한 경우, 부모 클래스의 기능은 자식에게
        가려진다.
    → 이렇게 부모의 기능을 재정의하는 것을 메서드 Override라 한다.
  • 하나의 이름으로 다양한 효과 얻기
    → 모든 자식 클래스가 동일한 이름의 메서드를 갖게 되므로 각 객체에 대하여 attack()이라는 이름을 사용하여 서로
        다른 형태를 구현할 수 있게 된다.

 

1-1. super 키워드

  • 클래스의 상속 관계에서 자식 클래스가 부모 클래스를 가르키는 예약어
  • 사용방법
    → 멤버변수 이름 앞에 명시
        : 부모 클래스의 멤버변수를 의미한다. 하지만 부모 클래스의 멤버변수는 이미 모두 상속되어 있기 때문에 이
          경우에는 this 키워드를 사용하는 것과 동일한 결과라서 멤버변수 앞에는 잘 사용하지 않는다.
    → 메서드 이름 앞에 명시(오버라이드 때문에 같은 이름의 메소드가 있을 수 있어서 구분하는 용도로 쓰임)

        : 부모 클래스의 메서드를 의미한다.
        : 재정의(Override) 되지 않은 메서드
          - 이미 상속되어 있기 때문에 this 키워드를 사용하는 것과 동일한 결과를 갖는다.
         : 재정의(Override)된 메서드
           - Override된 메서드 이름 앞에 사용하게 되면 재정의되기 이전의 원본 메서드를 의미한다.
    → 키워드 자체를 메서드처럼 사용
        : super();
          부모 클래스의 생성자를 의미한다.


 

▶ 지금 상태에서 출력하면 "안녕하세요."가 출력된다

▶ 부모 클래스의 say() 메서드를 출력하고 싶으면 어떻게 해야 할까?

▶ 부모 클래스의 say() 메서드를 자식 클래스에 직접 써줘야 할까?

▶ 그렇게 하면 부모 클래스에서 수정이 있을 시 자식 클래스에서도 손수 바꿔줘야 한다.

▶ 이 때 super.say()를 사용하면 간편해진다.


 

1-2. 상속 관계에서의 생성자 처리

  • 생성자가 정의된 클래스의 상속을 제한다.
  • 생성자는 상속되지 않는다.
  • 하지만 생성자가 정의된 클래스는 객체 생성을 위해서 생성자 파라미터를 반드시 전달받아야 하기 때문에, 파라미터를 갖는 생성자가 정의된 클래스를 상속 받게 되면 에러가 발생된다.
  • 부모 생성자의 강제 호출
    → 생성자가 정의된 클래스를 상속받은 경우에는 자식 클래스의 생성자를 통해서 부모 생성자를 강제로 호출해야 한다.
    → 부모의 생성자를 호출하는 방법은 super 키워드를 메서드 이름으로 사용하는 것이다.

파라미터가 있는 부모클래스 상속
생성자가 있는 부모 클래스 상속(생성자 강제호출)

 


 

▶ 파라미터가 있는 부모생성자를 받기 위해 자식 생성자에도 파라미터를 만들어준다.

▶ super()에서 바로 값을 적으면 데이터가 고정되어 수정이 용이하지 않으므로, super(str)로 받아준다.

▶ 이후 메인 클래스에서 값을 받으면 super(str)로 전달된 후 부모 클래스의 부모 생성자로 전달된다.


 

 

1-3. 메서드 재정의 과정에서 오타가 발생한 경우

  • 부모 클래스의 say() 메서드를 재정의하는 과정에서 개발자의 실수로 인해 "sai()"라고 메서드가 추가되었다면, Java는 새로운 메서드를 추가한 것으로 인식하고, 특별한 에러를 표시하지 않는다.
  • say() 메서드가 재정의 된 상태라고 생각한 개발자는 이 경우 의도하지 않은 결과를 만나게 될 것이다.

 

1-4. @Override(Annotation Override) 옵션

  • "@Override"는 이 키워드가 명시된 위치 아래에 정의되는 메서드가 부모 클래스에 존재하지 않을 경우 구문 에러로 처리한다.
  • 부모 클래스의 메서드를 재정의하고자 할 경우 의도치 않은 실수를 예방하기 위한 '오타 방지 옵션'이다.
  • 여러 개의 메서드를 재정의한다면 재정의되는 모든 메서드를 위해 각기 명시해야 한다.

 


▶ 맨 처음에 있던 그림 파일 실습

부모클래스 Unit

▶ getter, setter는 중요하기 때문에 무조건 만들어준다.

▶ 단축키 : alt+shift+s > r(Generate getters and setters..)

 

자식클래스 Army

생성자를 생성하면서 부모 생성자의 파라미터와 멤버변수를 받아온다.

attack()은 자식클래스마다 다르므로 오버라이드 해준다.

Army 클래스 만의 메소드 tank()를 만들어준다.

 

자식클래스 Navy

부모클래스를 상속받아 왔으므로 getName() 메소드는 이미 자식 클래스가 갖고 있다.

따라서 this.나 super.나 동일한 역할을 하며, 아무것도 쓰지 않고 getName()만 써도 문제 없다.

Army와 마찬가지로 새로운 기능의 메소드 추가

 

자식클래스 AirForce

@Override(Annotation Override) ★★★

▶ 오버라이드를 할 때 명시하는게 좋다. 철자가 틀리는 등 잘못되었을 때 컴파일러가 오류로 알려준다.

단축키 : alt+shift+s > v(Override/implement method..)

 

메인 클래스에서 실행

728x90

+ Recent posts