본문 바로가기
✏️Java 공부/Java의 정석

[Java 공부/Java의 정석] Chapter.07 : 객체지향 프로그래밍 2 - 2 (오버라이딩)

by 코코의 주인 2022. 7. 6.

오버라이딩

 부모 클래스로부터 상속받은 메서드의 내용을 변경하는 것을 오버라이딩이라고 한다. 상속받은 메서드를 그대로 사용하기로 하지만, 자식 클래스 자신에 맞게 변경해야하는 경우가 많다. 이럴 때 부모의 메서드를 오버라이딩한다.

예제

class point {	//2차원 좌표
    int x;
    int y;
    
    String getLocation() {
    	return "x: " + x + ", y: " + y;
    }
}

2차원 좌표계의 한 점을 표현하기 위한 point 클래스가 있을 때, 이를 부모로 하는 3차원 좌표계의 한 점을 표현하기 위한 point3D 클래스를 새로 작성하였다고 하자. point 클래스의 getLocation()은 한 점의 x, y좌표를 문자열로 반환한다.

class point3D extends point {	//3차원 좌표
    int z;
    
    String getLocation() {	//오버라이딩
    	return "x: " + x + ", y: " + y + ",z: " + z;
    }
}

point3D 클래스는 3차원 좌표게를 나타내기 때문에 한 점의 x, y, z 좌표를 문자열로 반환해야 한다. 때문에 이 메서드를 point3D 클래스에 맞게 z축의 좌표값도 포함하여 반환하도록 오버라이딩 한다.


오버라이딩의 조건

오버라이딩은 메서드의 내용만을 새로 작성하는 것이므로 메서드의 선언부는 부모의 것과 완전히 일치해야 한다. 그래서 오버라이딩이 성립하기 위해서는 다음과 같은 조건을 만족해야 한다.

자식 클래스에서 오버라이딩하는메서드는 부모 클래스의 메서드와
- 이름이 같아야 한다.
- 매개변수가 같아야 한다.
- 반환타입이 같아야 한다.

 다만 접근 제어자와 예외는 제한된 조건 하에서만 다르게 변경할 수 있다.

 

1. 접근 제어자는 부모 클래스의 메서드보다 좁은 범위로 변경할 수 없다.

- 만일 부모 클래스에 정의된 메서드의 접근 제어자가 protected라면, 이를 오버라이딩하는 자식 클래스의 메서드는 접근 제어자가 protected나 public이어야 한다.

 

2. 부모 클래스의 메서드보다 많은 수의 예외를 선언할 수 없다.


오버로딩 VS 오버라이딩

 오버로딩과 오버라이딩은 서로 혼동하기 쉽지만 그 차이는 명백하다. 오버로딩은 기존에 없는 새로운 메서드를 추가하는 것이고, 오버라이딩은 부모로부터 상속받은 메서드의 내용을 변경하는 것이다.

오버로딩(overloading) 기존에 없는 새로운 메서드를 정의하는 것
오버라이딩(overriding) 상속받는 메서드의 내용을 변경하는 것

  아래 코드를 보고 오버로딩과 오버라이딩을 구별해보자.

class parent {
    void parentMethod();
}

class child extends parent	{
    void parentMethod();	//오버라이딩
    void parentMethod(int i);	//오버로딩
    
    void childMethod();
    void childMethod(int i);	//오버로딩
}

super

super은 자식 클래스에서 부모 클래스로부터 상속받은 멤버를 참조하는데 사용되는 참조변수이다. 멤버변수와 지역변수의 이름이 같을 때 this를 붙여서 구별했듯이 상속받은 멤버와 자신의 멤버가 이름이 같을 때는 super를 붙여서 구별할 수 있다.

 this와 마찬가지로 super 역시 static메서드에서는 사용할 수 없고 인스턴스 메서드에서만 사용할 수 있다.

예제

class parent {
    int x = 10;
    void parentMethod() {
        System.out.println("parent");
    }
}

class child extends parent {
    void print() {
        System.out.println("x = " + x);			//parent의 x
        System.out.println("this.x = " + this.x);	//parent의 x
        System.out.println("super.x = " + super.x);	//parent의 x
    }
}
public class override {
    public static void main(String args[]) {
        child c = new child();
        c.print();
    }
}
실행 결과

x = 10
this.x = 10
super.x = 10

 

class parent {
    int x = 10;
    void parentMethod() {
        System.out.println("parent");
    }
}

class child extends parent {
    void print() {
        int x = 20;
        System.out.println("x = " + x);			//child의 x
        System.out.println("this.x = " + this.x);	//child의 x
        System.out.println("super.x = " + super.x);	//parent의 x
    }
}
public class override {
    public static void main(String args[]) {
        child c = new child();
        c.print();
    }
}
실행 결과

x = 20
this.x = 20
super.x = 10

 이전 예제와 달리 같은 이름의 멤버변수가 부모 클래스인 parent에도 있고 자식 클래스인 child 클래스에도 있다. 이 경우에는 super.x와 this.x는 서로 다른 값을 참조하게 된다. super.x는 부모 클래스로부터 상속받은 멤버변수 x를 뜻하며, this.x는 자식 클래스에 선언된 멤버변수를 뜻한다.

 이처럼 부모 클래스에 선언된 멤버변수와 같은 이름의 멤버변수를 자식 클래스에서 중복해서 정의하는 것이 가능하며 참조변수 super를 이용해서 서로 구별할 수 있다.

 변수만이 아니라 메서드 역시 super를 써서 호출할 수 있다. 특히 부모 클래스의 메서드를 자식 클래스에서 오버라이딩한 경우에 super를 사용한다.


총평

 이번 주에 집중이 안 된다.

 이 글 쓰는데 놀랍게도 3일이 걸렸다.

 와 이제 진짜 정신 차려야지.

댓글