Overriding(오버라이딩)이란?
부모 클래스로부터 상속받은 메서드를 자식클래스에서 재정의하는 것
오버라이딩 규칙
1. 선언부는 같아야 한다.(일반적으로 부모의 메서드 정의와 동일하게 정의)
2. 접근 지정자와 예외클래스 선언은 변경이 가능하지만 다음과 같은 조건을 갖는다.
- 접근지정자가 작아질 수 없다.
- 조상의 예외 개수보다 자식의 예외 개수가 많을 수 없다.
다음 예제를 작성한다.
package exam;
class Point2D {
int x;
int y;
void printPoint() {
System.out.println("[" + x + "," + y + "]");
}
}
class Point3D extends Point2D {
int z;
void printPoint() {
System.out.println("[" + x + "," + y + "," + z + "]");
}
}
public class Exam {
public static void main(String[] args) {
Point2D pos1 = new Point2D();
pos1.x = 10;
pos1.y = 20;
pos1.printPoint();
Point3D pos2 = new Point3D();
pos2.x = 10;
pos2.y = 20;
pos2.z = 30;
pos2.printPoint();
}
}
Point2D클래스의 printPoint()메서드가 x, y를 출력하는 기능을 갖는다.
Point3D클래스의 printPoint()메서드가 x, y, z를 출력하는 기능을 갖는다.
위 코드를 보면 Point2D를 상속받아 Point3D를 정의했고 z값까지 출력하는 메서드를 만들 때
부모가 가진 printPoint와 이름을 동일하게 정의하고 z까지 포함해서 출력하도록 정의하였다.
위와 같이 부모의 메서드와 동일한 선언으로 내용을 재정의 하는 것을 Overriding(오버라이딩)이라 한다.
오버라이딩을 하면 뭐가 좋을까?
객체지향에서 중요한 객체의 다형성 표현을 할 수 있게 한다.
다음 예제를 보자.
package exam;
class Point2D {
int x;
int y;
void printPoint() {
System.out.println("[" + x + "," + y + "]");
}
}
class Point3D extends Point2D {
int z;
void printPoint() {
System.out.println("[" + x + "," + y + "," + z + "]");
}
}
public class Exam {
public static void main(String[] args) {
Point3D pos3d = new Point3D(); // 자식 객체를 자식타입으로 참조
pos3d.x = 1;
pos3d.y = 2;
pos3d.z = 3;
pos3d.printPoint();
Point2D pos2d = pos3d; // 자식객체를 부모타입으로 참조
pos2d.x = 10;
pos2d.y = 20;
pos2d.printPoint();
}
}
실행결과
위 코드에서 Point3D pos3d = new Point3D(); 부분에서 자식 객체를 생성하였다.
그리고 각 멤버필드에 값을 대입하고 pos3d.printPoint()메서드를 호출한 결과
[1,2,3]이 출력 되었다. 여기까지는 이해가 가능하다.
그 다음이 중요한데 Point2D pos2d 참조변수는 부모객체를 참조할 수 있는데 거기에 타입이 다른
자식 객체를 참조하도록 하였으나 에러가 발생하지 않는다.
타입(자료형)이 다른데 참조가 된다?
위 의문은 꼭 이해하고 알아두어야 하는데 상속은 is ~ a 개념이 성립되어야 한다.
즉 자바의 모든 클래스는 Object를 상속받는다라는 것은 자바의 모든 객체를 Object타입으로 관리하겠다는 것. 예를 들어 세상의 모든 "살아있는 것"은 "생물"이라고 정의할 수 있는 개념과 같다.
아무리 수많은 종류의 생물이 있어도 결국 모두를 이야기할 때 "생물"이라고 표현할 수 있는 것이다. 이것이 다형성의 표현이다.
따라서 상속을 사용하면 부모와 자식객체는 서로 다른 타입이 아닌 같은 타입이라고 생각할 수 있고 자식객체가 생성될 때 super()부모 생성자를 호출하여 부모 객체생성 후 자식객체가 생성되므로 부모의 참조변수로 자식객체를 참조할 수 있다.
그림으로 표현하면 다음과 같이 이해할 수 있겠다.
위 그림에서 오버라이딩 된 메서드는 실제 생성된 객체에 정의된 메서드로 연결된다.
printPoint()메서드를 사용하면 Point3D로 객체를 생성했기 때문에
Point2D에 있는 메서드 대신 Point3D에 오버라이딩된 메서드가 호출된다.
다음으로 다형성을 표현하는 개념을 그림으로 확인한다.
Point2D타입을 참조하는 pos2d참조변수가 Point3D객체를 참조하는 형태를 표현한 것이다.
실제 만들어진 객체가 Point3D인데 Point2D를 생성한 후에 만들어지므로 위와 같이
pos2d가 참조하는 타입이 객체에 존재하므로 문제없이 참조가 가능한 것이다.
단, 그림에서 표현된 것과 같이 오버라이딩 메서드를 제외하고 자식멤버는 접근이 불가하다.
위와 같은 형태를 업캐스팅(up-casting) 형변환이라 한다.
위 객체를 원래의 타입으로 다시 대입할 수 있는데 이것은 다운캐스팅(down-casting) 형변환이라 한다.
다음 그림으로 개념을 확인
Point3D pos 참조는 Point3D를 참조할 수 있는데
pos2d는 Point3D객체의 멤버 중 부모타입 만큼만 식별이 가능하므로 자동 대입이 불가능하다.
따라서 다음과 같이 명시적 형변환을 통해 원래의 형태로 변환하여 참조가 가능하다.
위와 같은 개념으로 자바에서 다형성을 표현하게 된다.
다형(多形)성이란?
하나의 타입으로 여러 타입으로 파생된 타입의 객체들을 참조할 수 있고
오버라이딩된 메서드는 생성된 타입의 메서드가 호출되도록 동작하므로
하나의 메서드 호출이 여러 형태를 나타낼 수 있도록 하는 것이다.
'교육자료 > Java' 카테고리의 다른 글
Java 객체 비교하기 (0) | 2017.06.25 |
---|---|
Java 클래스 구성 요소(다형성) (0) | 2017.06.25 |
Java 클래스 구성 요소 (0) | 2017.06.25 |
Java 클래스 구성 요소 (상속) (0) | 2017.06.23 |
Java 클래스 구성 요소 (중첩클래스) (0) | 2017.06.22 |