오버라이딩
조상 클래스로부터 상속받은 메소드의 내용을 변경하는 것을 오버라이딩이라고 한다.
오버라이딩은 위와 같은 형태로 이루어진다.
오버라이딩의 조건
오버라이딩은 메소드의 내용만 새로 작성하는 것이며, 선언부는 조상클래스와 완전히 일치해야 한다. 따라서 오버라이딩이 성립하기 위해서는 아래의 조건이 필요하다.
조상클래스의 메소드와
- 이름이 같아야 한다.
- 매개변수가 같아야 한다.
- 반환타입이 같아야 한다.
단 접근 제어자와 예외는 제한된 조건 하에서만 다르게 변경이 가능하다.
- 접근제어자를 조상 클래스의 메서드보다 좁은 범위로 변경할 수 없다
(조상의 메소드가 protected라면 오버라이딩하는 자손 메소드는 protected 혹은 public이어야만 한다.)
- 예외는 조상 클래스의 메소드보다 많이 선언할 수 없다.
(Exception은 최고 단계의 예외처리이기 때문에, 가장 많은 예외를 처리하도록 하는 것이라는 걸 유의)
- 인스턴스 메소드를 static메소드로 또는 그 반대로 변경할 수 없다.
(서로 생성되는 시점이 다르기 때문)
오버로딩 vs 오버라이딩
오버로딩 : 기존에 없는 새로운 메소드를 정의하는 것
오버라이딩 : 상속받은 메소드의 내용을 변경하는 것
super
super는 자손 클래스에서 조상 클래스로부터 상속받은 멤버를 참조하는데 사용되는 참조변수다. 멤버변수와 지역변수의 이름이 같을 때 this를 통해 구별한 것 처럼 상속받은 멤버와 자신의 멤버가 이름이 같을 때 super을 붙여서 구별이 가능하다.
조상멤버와 자신의 멤버를 구별하는데 사용된다는 것 외에는 this와 다를 것이 없다. 모든 인스턴스 메소드에서는 자신이 속한 인스턴스의 주소가 지역변수로 저장되며, 이는 참조변수인 this와 super의 값이 된다.
static메서드는 인스턴스와 관련이 없기 때문에 this와 마찬가지로 super 역시 static메소드에서는 사용할 수 없다.
위의 예제처럼 조상 클래스에 선언된 멤버 변수와 자손 클래스에 선언된 멤버변수의 이름이 같더라도 super을 통해서 구별이 가능하다.
이 예제는 위에서 봤던 예제인데 상속받은 getLocation메소드에 super를 사용하여
return super.getLocation +"z : "+z;
로 나타낼 수 있다.
조상 클래스의 메소드의 내용에 추가적으로 작업을 덧붙이는 경우라면 이처럼 super을 사용해서 조상 클래스의 메소드를포함시키는 것이 좋다. 나중에 조상 클래스의 메소드가 변경되면, 그 변경사항이 자손클래스에 그대로 반영될 것이기 때문이다.
super() - 조상 클래스의 생성자
this()와 마찬가지로 super() 또한 생성자다. 차이점은 this()는 같은 클래스의 다른 생성자를 호출하는데 사용되지만, super()은 조상 클래스의 생성자를 호출하는데 사용된다는 것이다.
자손 클래스의 인스턴스를 생성하면, 자손의 멤버와 조상의 멤버가 모두 합쳐진 인스턴스가 생성되면서 자손 클래스는 조상 클래스의 멤버를 사용할 수 있게 된다.
이때 조상 클래스 멤버의 초기화가 수행되어야 하기 때문에 자손 클래스의 생성자에서 조상 클래스의 생성자가 호출되는 것이다.
자손 클래스의 첫 줄에서 super()를 통해 조상 클래스의 생성자를 호출해야 하는 이유는 자손 클래스의 멤버가 조상 클래스의 멤버를 사용할 수도 있으므로, 조상의 멤버들이 먼저 초기화되어 있어야 하기 때문이다.