Override

치로·2024년 7월 19일

Override

1. 오버 라이드란?

/// 신입 기술 면접에 많이 나옴

  • 부모 클래스에 정의된 것과 동일한 이름을 갖는 메서드를 자식 클래스가 정의한 경우, 부모 클래스의 기능은 자식에게 가려짐
  • 이렇게 부모의 기능을 재정의하는 것을 @Override라 함

2. 하나의 이름으로 다양한 효과 얻기

  • 모든 자식 클래스가 동일한 이름의 메서드를 갖게되므로 각 객체에 대하여 attack()이라는 이름을 사용하여 서로 다른 형태를 구현 가능
    /// class는 자바 당 하나, 그림은 그냥 참고용

super 키워드

: 클래스의 상속 관계에게 자식 클래스가 부모 클래스를 가리키는 예약어

1. 사용 방법

///this랑 비교해서 공부

  • 멤버 변수 이름 앞에 명시 : 부모 클래스의 멤버 변수를 의미
    하지만 부모 클래스의 멤버 변수는 이미 모두 상송되어 있기 때문에 이 경우에는 this 키워드를 사용하는 것과 동일한 결과이기에 잘 사용하지 않음
  • 메서드 이름 앞에 명시하는 경우 : 부모 클래스의 메서드를 의미
  • 재정의 되지 않은 메서드 : 이미 상속되어 있기 때문에 this 키워드를 사용하는 것과 동일한 결과를 갖음
  • 재정의 된 메서드 : override된 메서드 이름 앞에 사용하게 되면 재정의 되기 이전의 원본 메서드를 의미
  • 키워드 자체를 메서드처럼 사용 : 부모 클래스의 생성자를 의미

2. 상속을 통한 메서드의 기능 확장 처리




  • Hello 클래스가 Korean에 상속되고, Korean클래스가 say() 메서드를 Override 처리하게 되면 Korean 클래스의 객체는 더 이상 부모의 say() 메서드에 접근할 수 없음
  • 만약 부모 클래스가 가지고 있는 say() 매서드에 추가적인 기능을 구현하고자 한다면 부모의 코드를 그대로 복사해서 사용
  • 원본 기능에 대한 수정이 발생할 경우 부모 클래스와 자식 클래스를 모두 수정해야 하기 때문에 소스 코드의 유지 보수 효율성이 떨어지게 됨
  • super 키워드 : 부모 클래스의 메서드를 호출하는 기능을 가지고 있기 때문에,
    Override된 자식 클래스의 메서드에서 super 키워드를 사용하면, 재정의 되기 이전의 부모 클래스에 대한 메서드를 호출할 수 있음
  • super 키워드를 사용하여 부모의 메서드를 호출한 뒤에 추가적인 기능을 정의하고 있으므로, 부모의 원본 메서드에 대한 기능 확장 효과가 있음

3. 상속 관계에서의 생성자 처리

  • 생성자가 정의된 클래스의 상속 제한
  • 생성자는 상속되지 않음
  • 하지만 생성자가 정의된 클래스는 객체 생성을 위해서 생성자 파라미터를 반드시 전달받아야 하기 때문에,
    파라미터를 갖는 생성자가 정의된 클래스를 상속받게 되면 에러 발생

@Override 옵션

  • 메서드 재정의 과정에서 오타가 발생한 경우
  • 부모 클래스의 say() 메서드를 재정의하는 과정에서 개발자의 실수로 인해 "sai()"라고 메서드가 추가되었다면 java는 새로운 메서드를 추가한 것으로 인식하고, 특별한 에러표시를 하지 않음
  • 메서드 재정의 과정에서의 오타 방지 옵션
  • @Overrivde는 이 키워드가 명시된 위치 아래에 정의되는 메서는가 부모 클래스에 존재하지 않을 경우 구문 에러로 처리
  • 부모 클래스의 메서드를 재정의 하고자 할 경우 의도치 않은 실수를 예방하기 위한 '오타 방지 옵션'
  • 여러 개의 메서드를 재정의 한다면 재정의 되는 모든 메서드들 위에 각기 명시

예시 코드

package override;

class Hello {
	public void say() {
		System.out.println("hello");
	}
}

class English extends Hello {
	
}

class Korean extends Hello {
	public void say() {
		System.out.println("인녕하세요");
	}
}

public class Main01 {

	public static void main(String[] args) {
		// 자식 클래스에 구현된 메서드가 없기 때문에, 부모 클래스에 정의된 메서드를 찾아가게 됨
		English e = new English();
		e.say();
		// 자식 클래스가 부모와 같은 이름의 메서드를 정의하고 있기 때문에 k객체에게는 부모 클래스가 정의하고 있는 say()메서드가 가려지게 됨
		// 자식의 메서드가 우선시
		Korean k = new Korean();
		k.say();
	}

}
package override;

class Parent {
	public Parent(String msg) {
		System.out.println(msg);
	}
}
class Child extends Parent {
	// 부모 생성자를 강제 호출
	// : 생성자가 정의된 클래스를 상속받은 경우에는 자식 클래스의 생성자를 통해서 부모 생성자를 강제로 호출
	// - 부모의 생성자를 호출하는 방법은 super 키워드를 메서드 이름으로 사용하는 것
	// - 부모와 동일한 파라미터를 받도록 생성자를 정의하고, 전달받은 파라미터를 부모에게 재전달한다
	public Child(String msg) {
		super(msg);
	}
	
}

public class Main02 {

	public static void main(String[] args) {
		
	}

}
package override;

public class Unit {
	private String name;

	public Unit(String name) {
		super();
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	public void attack () {
		System.out.println(this.name + " >> 공격 준비");
	}

	public void nucleus() {
		System.out.println(this.name + " >> 핵미사일 공격");
	}
	
	public void bombing() {
		System.out.println(this.name + " >> 폭격 시작");
	}
}
package override;

public class AirForce extends Unit{
	
	public AirForce(String name) {
		super(name);
	}
	
	@Override
	public void attack () {
		super.attack();
		System.out.println(super.getName() + " >> 공중 공격 실행");
	}
	
	public void bombing() {
		System.out.println(super.getName() + " >> 폭격");
	}
}
package override;

public class Army extends Unit{

	public Army(String name) {
		super(name);
	}
	
	@Override
	public void attack () {
		super.attack();
		System.out.println(super.getName() + " >> 지상 공격 실행!");
	}
	
	public void tank() {
		System.out.println(super.getName() + " >> 탱크 공격!");
	}
}
package override;

public class Navy extends Unit{
	
	public Navy(String name) {
		super(name);
	}
	
	@Override
	public void attack () {
		super.attack();
		System.out.println(super.getName() + " >> 어뢰 발사!");
		System.out.println(super.getName() + " >> 지상 상륙");
	}
		
	public void nucleus() {
		System.out.println(super.getName() + " >> 탱크 공격!");
	}
}
package override;

public class Main03 {

	public static void main(String[] args) {
		Army am = new Army("육군");
		am.attack();
		am.tank();

		Navy na = new Navy("해군");
		AirForce ai = new AirForce("공군");
		
		na.attack();
		na.nucleus();	
		ai.attack();
		ai.bombing();
	}

}

0개의 댓글