본문 바로가기

프로그래밍언어/JAVA

[JAVA] 오버라이딩 (Overriding)

반응형

1. 오버라이딩

오버라이딩이란 조상 클래스로부터 상속받은 메서드의 내용을 변경하여 사용하는 것이다. 상속받은 메서드의 이름은 유지하면서 메서드의 내용을 변경하여 덮어씌우는 것으로 이해하면 된다. 메서드의 이름은 동일하지만 실행되는 것은 다른 메서드인 것이다.

 

class Parent {
	public void cal(int a, int b) {
		return a + b;
	}
}

class Child extends Parent {
	public void cal(int a, int b) {
		return a * b;
	}
}

 

자식 클래스인 Child는 Parent를 상속받았기 때문에 Parent의 cal 메서드를 사용할 수 있다. 하지만 이 경우에는 자식 클래스인 Child에 메서드 cal이 새로 구현이 되어있다. 그렇기 때문에 Child 클래스의 인스턴스에서 cal 메서드를 사용하는 경우 Parent의 cal이 아니라 Child의 cal이 동작하게 된다.


2. 오버라이딩의 조건

오버라이딩은 메서드의 내용만 재작성 하는 것이기 때문에 메서드의 선언부는 그대로 유지되어야 한다.

 

오버라이딩 조건

- 메서드의 이름이 같아야 한다.
- 매개변수가 같아야 한다.
- 반환타입이 같아야 한다.

 

이를 요약하자면 메서드의 선언부가 일치해야 한다는 것이다. 다만 접근 제어자와 예외는 제한된 조건에서 다르게 변경할 수 있다.

- 접근 제어자는 조상 클래스의 메서드보다 좁은 범위로 변경할 수 있다.

접근 제어자는 private < default < protected < public 순으로 넓어진다. 자식 클래스에서 오버라이딩 하는 경우 조상 클래스의 메서드의 접근 제어자와 같거나 더 좁은 범위로 선언할 수 있다.

- 조상 클래스의 메서드보다 많은 수의 예외를 선언할 수 없다.

오버라이딩한 메서드의 예외는 오버라이딩 된 부모 클래스의 메서드에 선언된 예외가 아닌 새로운 예외를 선언할 수 없다.

- 인스턴스 메서드를 static 메서드로 또는 그 반대로 변경할 수 없다.

 


3. 오버로딩 vs 오버라이딩

- 오버로딩 (overloading): 기존에 없는 새로운 메서드를 정의하는 것. 클래스 내부에서 이름만 같은 다른 메서드를 정의하는 것.
- 오버라이딩 (overriding): 상속받은 메서드의 내용을 변경하는 것. 부모 클래스의 메서드와 같은 이름의 메서드를 정의하여 이를 덮어쓰는 것.

 

 

4. super

super는 자손 클래스에서 부모 클래스를 참조할 때 사용되는 변수이다. 클래스에서 클래스 자신을 의미하는 변수로 this를 사용하는 것과 같이 부모 클래스에 접근하기 위해서 super 를 사용한다.

물론 상속받은 경우에 this를 사용해도 상속받은 멤버에 접근할 수 있지만 해당 멤버의 이름이 중복되어 있는 등의 이유로 구분이 필요한 경우에는 super 를 사용하는 것이 좋다.

모든 인스턴스 메서드는 자신이 속한 인스턴스의 주소를 지역변수로 가지게 되는데, 이것이 this와 super의 값이 된다. 반면에 static 메서드 (클래스 메서드)는 인스턴스와 관련이 없다. 그렇기 때문에 this와 super는 static 메서드에서는 사용할 수 없고 인스턴스에서만 사용할 수 있다.

 

class Parent {
    public void cal(int a, int b) {
      return a + b;
    }
}

// 자식 클래스인 Child에서 super를 사용하여 Parent의 메서드 cal을 호출하여 사용한다.
class Child extends Parent {
  public void cal(int a, int b) {
  	return super.cal(a, b);
  }
}

 


5. super()

super() 는 조상 클래스의 생성자이다. 자손 클래스의 인스턴스를 생성하는 경우 생성자를 통해 초기화를 수행한다. 이때 조상 클래스의 초기화도 수행해야 하는데, 이때 조상 클래스의 생성자를 호출하여 이를 수행할 수 있다. 만약 명시적으로 super()를 호출하지 않는 경우 컴파일러가 자동으로 생성자를 추가한다. 그렇기 때문에 특정 매개변수를 넘겨주기 위해서는 생성자 가장 첫 줄에 명시적으로 super()를 사용하여 초기화 해주는 구문이 있어야 한다.

명시적으로 초기화를 해주지 않은 경우 컴파일러가 supser()를 추가로 호출한다. 이때 조상 클래스에 기본 생성자가 정의되어 있지 않은 경우에 컴파일 시에 자손 클래스 인스턴스를 생성하면서 에러가 발생할 수 있으니 이를 유의해야 한다.

이러한 초기화는 최상단 클래스인 Object 클래스까지 거슬러 올라가면서 생성자를 모두 호출하여 초기화를 수행한다.

반응형

'프로그래밍언어 > JAVA' 카테고리의 다른 글

[JAVA] 제어자 (Modifier)  (0) 2021.11.16
[JAVA] 자바 패키지  (0) 2021.11.08
[JAVA] 상속 (Inheritance)  (0) 2021.11.04
[JAVA] HashMap vs HashTable  (0) 2021.10.29
[JAVA] 변수의 초기화  (0) 2021.09.04