자바 (Java)/요약

Chpt 7. 객체 지향 프로그래밍 2 - 주제 2. 오버라이딩, 참조변수 super, 생성자 super()

학듄 2023. 10. 26. 12:26
728x90

1. 오버라이딩

 

조상의 메서드를 자손에 맞게 변경하는 것을 오버라이딩이라고 한다. 오버라이딩의 사전적 의미는 덮어쓰다이다.

 

오버라이딩의 조건은 다음과 같다.

 

(1) 선언부가 조상 클래스의 메서드와 같다.
(2) 접근 제어자 범위: 조상 클래스의 메서드 <= 자손 클래스의 메서드 
(3) 예외 개수: 조상 클래스의 메서드 >= 자손 클래스의 메서드

 

선언부는 반환 타입, 메서드 이름, 매개변수를 포함한다. (3)에서 단순히 개수가 중요한 것이 아니라 예외의 상속 관계 또한 중요하다. 예를 들어 조상의 메서드에서 IOException, SQLException을 throw 한다고 했을 때, 자손의 메서드에서 Exception을 throw 하면 Exception은 모든 예외의 최고 조상이므로 조상보다 많은 예외를 던지는 것이다.

 

[참고 1] 조상의 static 메서드를 자손에서 정의하는 것은 오버라이딩이 아니라 재 정의하는 것이다.

 

 

[참고 2] 오버라이딩 vs. 오버로딩

 

  정의 상속과의 관계
오버로딩 같은 메서드 이름의 새로운 메서드를 정의하는 것 X
오버라이딩 조상 클래스의 메서드를 자손에 맞게 변경하는 것 O

 

다음 코드의 주석을 잘 구분하여야 한다.

 

[예 1]

 

class Parent {
	void parentMethod() {}
}

class Child extends Parent {
	void parentMethod() {} // 오버라이딩
    void parentMethod(int i) {} // 오버로딩
    
    void childMethod() {} // 자손 메서드 정의
    void childMethod(int i) {} // 오버로딩
    void childMethod() {} // 중복 정의 에러
}

 

2. 참조 변수 super

 

참조 변수 super는 자손에서 조상의 멤버를 참조할 때 쓰는 참조 변수이다. 다음 표는 super와 this를 구분한 것이다.

 

  차이점 공통점
this 인스턴스 변수, 지역 변수 구분에 사용 (iv vs. lv) (1) 인스턴스 주소 값을 담고 있는 참조 변수
(2) 인스턴스 메서드(생성자 포함)에서만 사용 가능
(3) static 멤버에서 사용 불가
super 조상 멤버, 자손(자신) 멤버 구분에 사용

 

오버라이딩을 할 때 조상의 메서드와 중복되는 부분이 있다면 super.조상 메서드 이름()와 같이 포함시키는 것이 좋다.

 

3. 생성자 super()

 

생성자와 초기화 블럭은 자손의 클래스로 상속되지 읺기 때문에 생성자 super()는 조상의 생성자를 호출하는데 사용된다. 조상의 멤버는 조상의 생성자를 이용해 초기화하는 것이 바람직하기 때문에 super()를 쓴다.  주제 5.에서 다뤘던 생성자의 규칙과 함께 새로운 규칙을 추가해서 알아두자.

 

(1) 클래스 이름과 메서드 이름이 같다.
- 같은 클래스 안에서 생성자를 호출할 경우 반드시 클래스 이름 대신 this를 사용한다.
(2) 반환 타입이 없다.
(3) 모든 클래스에는 반드시 하나 이상의 생성자가 있다. (없는 경우에는 컴파일러가 자동으로 기본 생성자를 추가해준다.)
(4) (Object 클래스의 생성자를 제외한) 모든 생성자에는 반드시 하나 이상의 생성자(super(), this())가 있다.
- 한 생성자에서 다른 생성자를 호출할 경우 반드시 첫 줄에서만 호출할 수 있다.
- 없는 경우에는 컴파일러가 자동으로 super()를 추가해준다.

 

다음은 (4)을 반영하는  좋은 예시다.

 

[예 2]

 

class Point {
	int x, y;
    Point(int x, int y) {
    	this.x = x;
    	this.y = y;
    }
}

class Point3D extends Point {
	int z;
    
    Point3D(int x, int y, int z) {
    	this.x = x;
    	this.y = y;
        this.z = z;
    }
}

// main 메서드 포함한 클래스 생략

 

다음을 실행하면 에러가 발생하기 때문에 13, 14번째 줄을 super(x, y);로 바꾸어야 한다. 에러가 발생하는 이유는 Point3D의 생성자에 (4)의 규칙을 적용해 super() 즉 Point()가 호출되는데 이는 정의되지 않은 메서드이기 때문이다. 마찬가지로 (4)의 규칙을 적용하여 Point(x, y) 생성자에도 super() 즉 Object()가 호출된다. 이러한 이유로 조상의 멤버는 조상의 생성자로 초기화하고 기본 생성자 또한 항상 추가해주는 것이 좋다.

반응형